Thursday, December 15, 2011

A Better Ajax throbber

I’ve been messing with setting up an ajax throbber ( the little waiting icon or animated gif.  That’s what they call it.  It ain’t me. ).

Most examples show that you should put the show() logic right before you make your ajax call and then the hide() in the $.ajax.complete() event.  This has a number of problems. 

1) Unless you have just one single repository through which all ajax calls go ( and I do ) you end up putting the start throbber logic all over the place, wherever you make a call

2) unless you use a setTimeout function the throbber will always show even if just for a flash.  It’s much better to have a pause and if the ajax call is quick enough then you don’t see the throbber at all.

Number two has a major problem though.  And this is the meat of the post.  If you set your time out for 1000 ( one second ) and the ajax call comes back in 500 then the ajax complete will fire before your setTimeout has fired.  Then the setTImeout will fire and the throbber will never disappear.

Two ways to deal with this are to put the hide() logic in the repository call back method which unless you have a single repository as mentioned above with a single OnComplete callback that then calls your real callback you end up with code everywhere again.

So what I decided to do is to have global ( or scoped to your module global ) variable called showThrobber, and set it to false.  Then in the $.ajaxSetup.before send I put my timeout with a check for showThrobber. in the $.ajaxSetup.complete is set showThorb to false and hide the throbber.  so it looks like this

$.ajaxSetup({
            complete:function(){dci.showThrob = false;  $("#ajaxLoading").hide();},
            beforeSend:function(){setTimeout(function() {if(dci.showThrob) $("#ajaxLoading").show(); }, 500)}

});

In my ajax get ( or post ) I turn on the showThrob

ajaxGet:function(url, data, callback){
             dci.showThrob=true;
           // showLoader = setTimeout(function() {if(dci.showThrob) $("#ajaxLoading").show(); }, 1000);
            $.get(url,data,function(result){repositoryCallback(result,callback);
            });
        }

sorry about the formatting.

This is I believe called a latch mechanism.

No comments: