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: ,