Is it possible to automate the showing/hiding of a ajax loading gif, and the disabling/enabling of the submit button at the same time? (when the submit button is a styled < a > not a input type=submit)
Currently when submitting I do this:
$("#save_button_id").click(function () {
if ($('#save_button_id').hasClass('ui-state-disabled')) return false;
Save();
});
function Save() {
StartAjax($("#save_button_id"));
$.ajax({
success: function (data) {
EndAjax($("#save_button_id"));
// etc...
},
error: function (xhr, status, error) {
EndAjax($("#save_button_id"));
// etc ...
}
});
}
function StartAjax(button) {
DisableButtonClick(button);
$("#ajaxLoad").show();
}
function EndAjax(button) {
EnableButtonClick(button);
$("#ajaxLoad").hide();
}
I've seen a few places talk about how to use .ajaxStart() to automatically show the loading gif, but is it possible to also find a reference to the button (a styled < a > tag) that was clicked, and automatically disable/enable that as well?
The point of this is to not have to manually type in Start/EndAjax every time, and to make sure the app is consistent everywhere.
EDIT
None of the answers so far offer automation - any solution (like my current one above) where you have to manually type start/end before and after every single $.ajax() causes a maintenance problem: Its easy to forget to place the start/end next to some $.ajax() calls, and if you want to change how it works later you need to go through every single one to make the change.
EDIT 2 - to clarify point re the .delegate() suggestion
You said "You can attach your event handler to any element" - but I want to attach it to every button element (DRY!): so I've modified the 1st part of your suggestion to be:
$('div#buttons a.ui-icon').each(function(index) {
$(this).ajaxStart(function() {
$("#ajaxLoad").show();
});
});
This solves the first problem, which is how to show the loading .gif for any button, without having to repetitively type "$("#ajaxLoad").show()" everywhere there is an $.ajax() call.
The next part is how to disable any button when it is clicked (again with no repetitive code) - you suggested .delegate(). But in your example every button click will call the Save() method. (I changed the selector to match my html)
$('div#buttons a.ui-icon').delegate('button:not(.ui-state-disabled)', 'click', function() {
$(this).toggleClass('ui-state-disabled');
Save(); // this line needs replacing with a call to $(this).something
});
The problem with this is that $(this) is not always the save button (the selector returns ALL the buttons), it might be the delete button or the cancel button or etc. So calling $(this).toggleClass is fine, but calling Save() means you are calling the wrong function. All these buttons already have a .click method:
$("#SaveButton").click(function () {
Save();
});
$("#DeleteButton").click(function () {
Delete();
});
So this is the original click function that needs to be called where it says $(this).something above. At this point it should be calling the original click - or perhaps it is more correct to say it should then bubble up to the original .click. The .delegate must be more generic, and the original .click will provide the specific implementation.