I'm using jQuery and jQuery UI. I experienced that users sometimes fire the ajax-calls more than once, because the button/Link that triggers the call is not disabled right after they click it. To prevent that from happen, I now disable the button/link in my "beforeSend" -action.
This is what a typical Ajax Call looks like for me:
$.ajax({ type: "POST", url: "someURL" data: "someDataString", beforeSend: function(msg){ $(".button").button("disable"); }, success: function(msg){ $(".button").button("enable"); // some user Feedback } });
But I dont wann to add this button-Disable logic in every Ajax Call. Is there any way to globally define a function that gets called everytime before /after and ajax-call?
There are several ways to achieve what you are asking for. The only difference between them is how they are implemented, and it's up to you to choose which method works best for your specific case. The methods also depend on which version of jQuery you are using, so I will split this answer into two sections.
Adding multiple callbacks after init
Since jQuery 1.5 you can add multiple callbacks thanks to the overhauled API and newly introduced jqXHR
object that is returned by .ajax
. It implement the Promise (see Deferreds) interface, and we can use that to our advantage:
// fn to handle button-toggling var toggleButton = function() { var button = $(".button"); button.button(button.button("option", "disabled") ? "enable" : "disable"); } // store returned jqXHR object in a var so we can reference to it var req = $.ajax({ beforeSend: toggleButton, success: function(msg){ /* Do what you want */ } }).success(toggleButton); // we can add even more callbacks req.success(function(){ ... });
Using a prefilter
jQuery 1.5 also introduced prefilters which you can use to replace the global configuration of jQuery 1.4:
// good practice: don't repeat yourself, especially selectors var button = $(".button"); $.ajaxPrefilter(function(options, _, jqXHR) { button.button("disable"); jqXHR.complete(function() { button.button("enable"); }); });
Note: The jqXHR section of the $.ajax entry has this notice about using jqXHR.success()
:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
Events and global configuration
Use .ajaxStart
and .ajaxStop
to bind callbacks to a specific selector. The events that trigger these callbacks will fire off on all Ajax requests.
$(".button").ajaxStart(function(){ $(this).button("disable"); }).ajaxStop(function(){ $(this).button("enable"); });
Use .ajaxSetup
to setup a global ajax configuration. The settings object passed to .ajaxSetup
will be applied to all Ajax requests, even those made by the shorthands .get
, .getJSON
and .post
. Note that this isn't recommended since it can easily clobber its functionality.
$.ajaxSetup({ beforeSend: function(){ $(".button").button("disable"); }, success: function(){ $(".button").button("enable"); } });
Filter out requests in global event callbacks
If you need to filter out certain requests you can do that with.ajaxSend
and .ajaxComplete
where you can check the Ajax settings
object. Something like this:
var button = $(".button"); // fn to handle filtering and button-toggling var toggleButton = function(settings) { if (settings.url == "/specific/url") button.button(button.button("option", "disabled") ? "enable" : "disable"); } }; // bind handlers to the callbacks button.ajaxSend(function(e,x,settings){ toggleButton(settings); }).ajaxComplete(function(e,x,settings){ toggleButton(settings); });
This can also be done with the previously mentioned .ajaxSetup
by doing the same type of checks to the settings
object that is passed to the callback handlers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With