views:

79

answers:

4

Sometimes in my application there are many elements loading so I want to show the typical AJAX spinner above the control (or DOM node) with it disabled.

What is the easiest/best way to do that?

Ideally I would like to:

$("#myelement").loading();
$("#myelement").finishloading();

Or even better being able to do AJAX requests directly with the element:

$("#myelement").post(url, params, myfunction);

Being #myelement a regular node or form input.

A: 

what i've done in the past is, on post pass the element id (a containing div) to a function which replaces it's inner HTML with a loading image, and then in the post back replace it's content again with the updated real content.

pstanton
Could you provide a working example?
Eduardo
+2  A: 

You could use beforeSend and complete callbacks:

$.ajax({
    url: 'script.cgi',
    type: 'POST',
    beforeSend: function() {
        $('.spinner').show();
    },
    complete: function() {
        // will trigger even if request fails
        $('.spinner').hide();
    },
    success: function(result) {
        // todo: do something with the result
    }
});
Darin Dimitrov
Ideally you'd write a simple jquery plugin/wrapper to simplify this process ... but something must surely exist already?
Swizec Teller
+1  A: 

Since you're already using jQuery, you may want to look into BlockUI in conjunction with Darin Dimitrov's answer. I haven't used it yet myself as I just came across this today, but it looks decent.

If you're writing a semi-large-ish application and anticipate making many AJAX calls from different places in your code, I would suggest that you either add a layer of abstraction over $.ajax, or create a helper function to avoid having boiler plate for your UI indicator all over the place. This will help you out a lot should you ever need to change your indicator.

Abstraction method

var ajax = function(options) {
    $.ajax($.extend(
        {
            beforeSend: function() {
                $.blockUI();
            },
            complete: function() {
                $.unblockUI();
            }
        }, 
        options
    ));
};

ajax({
    url: 'script.cgi',
    type: 'POST',
    success: function(result) {
        // todo: do something with the result
});

Helper method

var ajaxSettings = function(options) {
    return $.extend(
        {
            beforeSend: function() {
                $.blockUI();
            },
            complete: function() {
                $.unblockUI();
            }
        }, 
        options
    );
};

$.ajax(ajaxSettings({
    url: 'script.cgi',
    type: 'POST',
    success: function(result) {
        // todo: do something with the result
    }
}));

Also, I wouldn't suggest overwriting the $.ajax method itself.

Justin Johnson
I am finnaly using jQuery BlockUI Element Blocking http://jquery.malsup.com/block/#element
Eduardo
A: 

If you want to show the spinner every when an ajax call is in progress I think you should use ajaxStart and ajaxStop.

$("#spinner")
  .ajaxStart(function(){$(this).show();})
  .ajaxStop(function(){$(this).hide();});
zesc