Reputation: 24717
I'm using jQuery 1.6.1 and I have checkbox that I want to programmatically check while also calling it's click event. Normally I just make this call:
$('#my_checkbox').click();
When the webpage first loads, the checkbox is not checked. When I make the above call, it does set off the click event as expected, but inside the click event this.checked
will still return false. When the click event is completed, the checkbox is then checked. It seems the click event (when programmatically triggered) is executed before the state change of the checkbox. If I actually click on the checkbox, this.checked
properly reflects the new state of the checkbox, i.e. it changes the state before firing the event.
Why when I programmatically call the click event does the event fire before the state change and what can I do to get around it?
Upvotes: 2
Views: 347
Reputation: 1074465
It's an interesting problem (which I've replicated here). The temptation, of course, would be to use change
handlers rather than click
handlers (example), but the problem is that change
doesn't fire at all on IE when you use click
to toggle the state. Which might be a good reason not to do that.
I suppose you could define your own mechanism that doesn't rely on click
performing the default action — a teeny little plug-in, or just a function you call and pass in a jQuery object. Here's a teeny plug-in version:
(function($) {
$.fn.flip = function() {
this.prop("checked", !this.prop("checked"));
this.triggerHandler("click");
this.triggerHandler("change");
};
})(jQuery);
Usage:
$('my_checkbox').flip();
Note that that off-the-cuff version will, if applied to jQuery object containing multiple checkboxes, force them all to the same value. You could loop if you want them to be independent:
(function($) {
$.fn.flip = function() {
this.each(function() {
this.checked = !this.checked;
});
this.triggerHandler("click");
this.triggerHandler("change");
};
})(jQuery);
By using triggerHandler
rather than trigger
, we avoid causing the default action.
The alternative would be for all of your click
handlers for checkboxes to use a timeout:
$("my_checkbox").click(function() {
var $this = $(this);
setTimeout(function() {
// Actually do something with $this
}, 0);
});
...which just seems like a maintenance nightmare.
Upvotes: 3