How to elegantly disable/enable all jQuery UI buttons?
I currently have several action buttons in different pages, and each button performs some AJAX call when clicked. In another word, I have code like this all over the places:-
$("#searchButton")
.button()
.click(function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
After doing some testing, it seems like some AJAX calls take at least more than a few seconds to process before the callback function is being called.
My plan is to disable the button when the AJAX call is made and enable it back when the AJAX call is completed. This is to prevent user from clicking the button too开发者_如何学编程 many times when the request is being processed. One solution I found is to utilize the unbind()
and bind()
functions. After modifying my code, it looks like this now:-
var searchButtonClickHandler = function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
};
$("#searchButton")
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", searchButtonClickHandler);
})
.click(searchButtonClickHandler);
This code works fine. Basically, it removes the click handler when the AJAX call is made and addes the click handler back when the AJAX call is completed.
My question is... is it possible to generalize the button disabling/enabling so that I don't have to implement ajaxStart()
and ajaxStop
on all UI buttons?
Ideally, I would like to use my earlier code snippet to register only the click event handler on the button, and then enable/disable all buttons using the .ui-button
selector, something like this...
$(".ui-button")
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
// not sure how to bind the handler here
$(this).button("enable").bind("click", ?? );
});
... but, this doesn't work and I run into trouble in binding the click handler here.
The more I think about it, it almost seems like I need to create a button builder function to do this, for example:-
var createButton = function(selectorName, clickHandler) {
$(selectorName)
.button()
.ajaxStart(function() {
$(this).button("disable").unbind("click");
})
.ajaxStop(function() {
$(this).button("enable").bind("click", clickHandler);
})
.click(clickHandler);
};
// create button like this
createButton("#searchButton", function() {
...
$.get(url, { data: ...}, function(data) { ... });
...
});
... but this approach will only disable/enable the selected button, and I want to apply that to all UI buttons.
Do anyone has a better approach in disabling/enabling all the buttons in the page?
Thanks.
Different approach, according to this answer you should be able to get a reference to your previous event handler via .data("events");
Putting that together with your sample it should look like this:
$(".ui-button")
.ajaxStart(function() {
var events = $(this).data("events");
$(this).data("oldEvent", events.click[0]);
$(this).button("disable").unbind("click", events.click[0]);
})
.ajaxStop(function() {
var oldClick = $(this).data("oldEvent");
$(this).button("enable").bind("click", oldClick.handler);
});
Not sure if this will work completely yet, still messing around on jsfiddle.
Update
This should work, example on jsfiddle.
you can use $('input[type=button]').attr('disabled','disable');
to disable all buttons instead of binding and unbinding click event to the buttons... also you can use deferred jquery object, here is an example
Maybe you could attach your handler to the parent element of your buttons with delegate
? That way there's only one handler function to bind/unbind.
Yahoo hosts a getElementByClass function, and you could assign a class such as "disableMe" to all your UI buttons. Then use getElementByClass('disableMe') to return an array of all the elements you want to disable.
The link: http://developer.yahoo.com/yui/dom/
You can use
$("button").each(function(){
//your code here
});
精彩评论