Multiple AJAX loading indicators
One of my biggest issues in the latest version of this site was how to get multiple AJAX loading indicators working on one page.
Getting a single AJAX loading progress indicator into your web application can be a relatively straightforward task thanks to a simple piece of Javascript from Thomas Fuchs:
// lang javascript
Ajax.Responders.register({
onCreate: function() {
if($('busy') && Ajax.activeRequestCount>0)
Effect.Appear('busy',{duration:0.5,queue:'end'});
},
onComplete: function() {
if($('busy') && Ajax.activeRequestCount==0)
Effect.Fade('busy',{duration:0.5,queue:'end'});
}
});
However, from what I could tell (and subsequently experienced) is that by using this code, you are limited to only one progress indicator per page. This caused me problems, as on my Archives page I have a progress indicator for when the application is fetching monthly archives, but also for the live search function that appears on every page. Whenever I activated an AJAX request by using either function, both the loading indicators would be displayed, thus confusing the user.
So, how is it possible to get around this? Well, from what I can see it’s impossible to pass the ID of a loading indicator into Thomas’ script. The trick is to move the hiding and displaying of the indicators into function calls for the “onComplete” and “onCreate” events within your specific AJAX request:
// lang javascript
function getMonthResults(vars)
{
var url = 'archives_month.php';
var pars = 'm=' + vars;
var target = 'monthResults';
var myAjax = new Ajax.Updater(target, url, {
asynchronous:true,
onCreate: function() { showLoader('mArchive_loader'); },
onComplete: function() { hideLoader('mArchive_loader'); },
parameters: pars,
method: 'get'
});
var element = document.getElementById(target);
}
The two events now call separate functions that pass the ID of the loading indicator, allowing you to define which indicator to hide or display:
// lang javascript
function showLoader(loader)
{
new Effect.Appear($(loader), {duration: 0.5});
}
function hideLoader(loader)
{
new Effect.Fade($(loader), {duration: 0.5});
}
Simple as that. Now, I’m not saying that this is the “offical” or “ideal” way of going about this task, but it’s the one that worked for me. You can also extend the show and hide functions, to add an effect to your target container by passing the target as well as the loader to the function. For example, I have used the following as my show and hide functions:
// lang javascript
function loadingRequest(loader, target)
{
new Effect.Appear($(loader), {duration: 0.5});
$(target).style.display = "none";
}
function completedRequest(loader, target)
{
new Effect.Fade($(loader), {duration: 0.5});
new Effect.BlindDown($(target));
}
This means that when the AJAX request has completed, the results will slide into view using the “BlindDown” effect from the Scriptaculous library. A nice added extra.
Technorati Tags: AJAX, Javascript
18 People Added Their Comments
Great article. I have blogged about it on http://www.thewebdesignblog.com
Test
d
t(“‘gt(szhy§’(h§’h§hj§e
Thanks! I’m building my first app using CakePHP and Prototype/Scriptaculous – this saved me some valuable figuring-out time while I’m on a tight deadline.
trtrtr
Great, thanks. Just what I was looking for.
test
Thanks!
Make your own Ajax loading indicators with http://www.webscriptlab.com
Great, thanks.
I just found an Ajax loading generator on http://www.webscriptlab.com, lets you generate loading icons on demand for your applications. Pretty cool stuff!
I got this to work with ‘onLoading’ rather than ‘onCreate’.
onCreate would just not work for me!
Best,
Sheri
Hi,
this is very simple and important information for AJAX Users.
good one.
http://mukeshvariya.blogspot.com
Using onLoading causes a problem in IE 6. Sometimes onLoading gets called after onComplete. It is suggested by the Prototype documentation that you avoid using onLoading because it’s not deterministic oon each browser.
does onCreate have these problems?
Hello! You have a Very good site! I like it! I just wanted to pass on a note to let you know
I only wish i came across this article sooner! Great read!
I am using this for showing the loading indicator everytime an Ajax call is made on different places from a page (see the … {Element.show(’show_tags_loading’);} and {Element.hide(’show_tags_loading’);}…):
———————-
Click here
———————–
Ops, it seems Wordpress eats the code (put for a href and other HTML tags):
———
a href=”javascript:void(0)” onClick=”new Ajax.Updater(‘form_add_new’,'display/show.cfm?page=1′, {onCreate: function(){Element.show(’show_tags_loading’);},onComplete:function(){Element.hide(’show_tags_loading’)},asynchronous:true});return false;” …Click here…. /a span id=”show_tags_loading” class=”normal” style=”display: none;” img src=”loading.gif” /span
————–