Option For Handling UX During Ajax Calls

Update: Added a short video showing the functionality in this example

mar-6-2017-11-01-am

The above GIF shows the functionality – as you can see the UI gets blocked with a message to “Please wait” – this is customisable by following the documentation on BlockUI page. Also, in the example, it takes a few seconds to get the “Managers name” – this is hardcoded to wait so that you can see the code in action for longer.

Ajax is a great technology and extremely useful for updating a form without the need to save and reload the form.

Often we use it in ServiceNow to facilitate form entry and giving the user additional data/restricting their data etc.

For example, a user enters a server CI on the form, we then update additional fields with current RAM and HDD space. The issue is however, these fields are editable while retrieving the data, and so a user might enter the data while the Ajax call is being created (sometimes the Ajax call is super fast, other times… not so much). So the solution I’m proposing below will automatically add a pop over to block the UI while the Ajax call is being made until it’s returned.

The syntax is identical to the standard GlideAjax except instead of instantiating a GlideAjax object, we will be using a custom one called GlideAjaxLock. The API then works like this:

var ga = new GlideAjaxLock("ScriptInclude");
ga.addParam("sysparm_name", "function_name");
ga.getXML(function() {
console.log("Finished");
});
}

What this will do is as soon as the getXML function is triggered, the UI will be blocked and will only be unblocked when the Ajax function is returned and the callback function run. How is this achieved?

Firstly, I imported JQuery BlockUI plugin and copied the code into a global UI script. We could have written some code to block the UI, it’s relatively trivial but for this example, the lazier option is to include the JQuery BlockUI and use its API.

Secondly, I then created a second global UI script which created the GlideAjaxLock object:

addLoadEvent( function(){
if (GlideAjax !== undefined) {
//Create a global variable called GlideAjaxLock and extend it from GlideAjax so it contains all of the same functions
window.GlideAjaxLock = Class.create();
GlideAjaxLock.prototype = Object.extendsObject(GlideAjax, {
//Override the getXML function
getXML : function(fun, additionalParams, responseParams) {
//As soon as the function is called, we block the UI using the plugin
$j.blockUI();
this.wantAnswer = false;
//We then create a new callback function which first runs the original callback which was passed in, once processing is complete, it then unblocks the UI
var callback = function(response) {
fun(response);
$j.unblockUI();
}
//This comes with the normal getXML function to make the actual call
this._getXML0(callback, additionalParams, responseParams);
},
});
}
});

Thats it, whenever you want to block the UI, just use GlideAjaxLock instead of GlideAjax and the rest remains the same.

If you’d like to extend this further, there’s nothing stopping you creating a new function that also allows the “Please Wait” message to be customised with each call. So for example, if it’s a Service Request that’s making an external interface call, the message could say “Retrieving real time information from xyz”.

It gives the customer a little more information about why they can’t do much at the moment and keeps them involved in the request.

5 Comments

      • Ah, I see. I can see that…more like a real-time ‘Please Wait while we do stuff…’ screen. In this case the GlideAjax is really just there to minimize the refreshing of the screen, not so much to prevent the UI from being blocked as we know it’ll be blocked for a bit and we also want to let the user know that.

        I can see that use case exactly as you mentioned, when retrieving external data that you rely upon for the next set of fields or questions. Nice work.

        Like

  1. What’s the use-case for this? Isn’t the idea of AJAX not to block the UI, so the user has a pain-free smooth experience. If they type something and it gets over-written, well too bad, It’s not nearly as bad as having everything seize up for a few seconds.

    Like

    • The idea of Ajax is getting data from the server without reloading the page. The idea of it being asynchronous is to not sieze up the screen. When it’s synchronous, it’s not so much that it stops input, but that the browser will seize up and feel like it’s crashing.
      This approach is to let the user know something is happening and should wait (overwriting user input isn’t good).

      True it wouldn’t (and shouldn’t) be used for every Ajax call, but certain ones it can be useful – eg I’ve seen a lot of service requests with interfaces to external systems built in to them, a really nasty solution in my mind, but the user will be oblivious anything is happening unless they’re savvy enough to monitor the network. With this, there could be a notice letting the user know what’s happening at least

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

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