Thursday, July 24, 2008

Adding Loading animation to all AJAX calls

So, you like AJAX, and your users like it except they can't tell when something is being done in AJAX. They complain that there is nothing that indicates to them that something is happening such as a query for a list, save, etc. One solution to this is to show an animated gif next to the element that caused the AJAX call in the first place. While the first line below and the BeginRequest() method are ASP.NET AJAX specific, the addLoadingAnimation() method is just JavaScript and can be used with Java, PHP, etc. The addLoadingAnimation() is IE and FireFox compatible on Windows, and has not been tested in any other browsers or platforms. The animation is removed in the endRequest event in ASP.NET when using an Update Panel. There is nothing needed because of how the Update Panel works. In other situations, the animation may need to be removed manually. Additional code would be needed, but should be able to be done in a similar way. The code assumes that the image for the text input will fit nicely inside the text input. A 16 x 16 image will probably work for text inputs of default height. The loading image for all other elements can be whatever size you like.
// Register our event listener that is called when an AJAX request is made.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequest);

function BeginRequest(sender, args) {
var srcElement = args.get_postBackElement();
addLoadingAnimation(srcElement);
}

// Adds a loading animated gif to the right of
// the element that started an element
// (Except if the element is a text input,
//  then the image is inside the text input
//  as a background image)
function addLoadingAnimation(srcElement)
{

// if element is a textfield, then show the loading image in the textfield itself.
if (srcElement.tagName == "INPUT" && srcElement.type == "text")
{      
   srcElement.style.backgroundImage = 'url(images/loading.gif)';
   srcElement.style.backgroundRepeat = "no-repeat";
   srcElement.style.backgroundPosition = "right";
}

// else the element looks better with the loading image to the right of the element
else
{
   // only add the animation if it isn't there already
   // i.e. user click link twice in a row
   if (srcElement.nextSibling == null
       ||
       (
           !srcElement.nextSibling.innerHTML
          || (
             srcElement.nextSibling.innerHTML
             && srcElement.nextSibling.innerHTML.indexOf("otherLoadingImage") == -1)
             )
      )
   {
      var anim = document.createElement("span");
      anim.innerHTML = '<IMG ID="otherLoadingImage" BORDER="0" SRC="images/loading.gif">';
      srcElement.parentNode.insertBefore(anim, srcElement.nextSibling);
   }
}
}

No comments: