ExtJS: Show a loading mask during Ajax calls

This is my first ExtJS post in a long while and sorry it’s not related to ExtJS4; maybe in the near future.Recently I was asked to implement a page wide mask during Ajax calls to prevent user from interfering with the current call by clicking on the screen or doing something they otherwise should not be doing while the call is running. I initially used the “wait:true” option of the Ext.MessageBox configuration, but the stakeholders did not like it since the progress bar it displayed was not synced to the actual length of the call. This is how I ended up implementing it:

function showLoadingMask(loadingMessage)
{
if (Ext.isEmpty(loadingMessage))
loadText = 'Loading... Please wait';
//Use the mask function on the Ext.getBody() element to mask the body element during Ajax calls
Ext.Ajax.on('beforerequest',function(){Ext.getBody().mask(loadText, 'loading') }, Ext.getBody());
Ext.Ajax.on('requestcomplete',Ext.getBody().unmask ,Ext.getBody());
Ext.Ajax.on('requestexception', Ext.getBody().unmask , Ext.getBody());
}

Hope it helps!

 

The meat of the functionality is in binding the mask() and unmask() function of the Ext.Element object to the ‘beforerequest’, ‘requestcomplete’ and ‘requestexception’ events of the Ext.Ajax object. I need a custom message to be displayed depending on the context that’s the reason why i encapsulated that logic in a function. I also tweaked my CSS a little to customize the mask style, overriding the ExtJS style, as well as the style of the message displayed to the user:


.ext-el-mask
{
color:gray;
cursor:default;
opacity:0.6;
background-color:grey;
}

.ext-el-mask-msg div {
background-color: #EEEEEE;
border-color: #A3BAD9;
color: #222222;
font: 1.2em tahoma,arial,helvetica,sans-serif;
}

.ext-el-mask-msg {

padding: 10px;

}

Advertisements

7 thoughts on “ExtJS: Show a loading mask during Ajax calls

  1. Pingback: JavaPins
  2. Useful code, but I have one small problem: body gets masked with a mask that is just enough to cover its z-index; but if there are some dialogs (ExtJS windows) open at the time of ajax request, they get in front of the body mask (and they are perfectly clickable, dragable, etc.). How can I apply the mask with a z-index that is always higher than all displayed elements?

  3. Very useful code, but I have one problem / question. If we mask only the body, the mask appears behind any open dialogs (ExtJS windows). How do we force the mask to appear in front of (i.e. on top of) the foremost open window? I know that I should set z-index to the mask, but how to find the currently max z-index and how to set it to the body mask?

    1. Hum… I think it’s standard behavior for the mask to be below any dialog. It would actually look weird and be counterintuitive to have open dialogs covered by the mask. But that’s just my opinion. I haven’t looked at this code in a while but you’d have to look at the ExtJS source code for setLoadingMask if I am not mistaken to check the value of the z-index set in the CSS.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s