Reputation: 1517
Here is my HTML:
<input class='user_roles' id="chk" type=checkbox />
<input id="btn_on" type="button" value="on" />
<input id="btn_off" type="button" value="off" />
And my jQuery:
$('#chk').click(function() {
if($(this).prop("checked") === true) {
alert ("checked");
}
else{
alert ("not checked");
}
});
$("[id$=btn_on]").click(function () {
$('#chk').click();
});
$("[id$=btn_off]").click(function () {
$('#chk').click();
});
A working example is here.
When the checkbox is clicked with the mouse it is checked straight away - that is, the alert displays "checked". However when one of the buttons is clicked, which indirectly call the click method on the checkbox, the checkbox is not clicked until after the click code has been run.
To test this, click the check box a couple of times with the mouse and you will see the alerts "checked" and "not checked" respectively. Click "On" and you will see the alert "not checked", and then the checkbox becomes checked. If you then click "Off" you will see "checked" followed by the checkbox unchecking itself.
What is the reason for this behaviour? How can I ensure that the checkbox "checking" happens before the click listener code is called, as per the mouse behaviour?
Upvotes: 7
Views: 732
Reputation: 5191
It seems to me the explanations is that this is a bug in the way the browser treats clicks on checkboxes:
The default behaviour should take place after the custom event handler is called. So what you see when you click the buttons is actually the correct behaviour. The funny behaviour is that when you click the box it is checked before the custom event handler is run.
To see how weird that is, you can return false;
from the event handler. This is supposed to prevent the default behaviour. What you'll see is that the box is actually checked when you click it - and then unchecked once the event handler returns!
By the way, I'm using Firefox 4. I don't know what it's like in other browsers. It seems not to be related to jQuery, as I can see the same funny behaviour when doing everything without it.
Upvotes: 1
Reputation: 822
if its just a question about getting it to work, use .change()
instead of .click()
on your check box, if its about why it does what it does i have no idea sorry
Upvotes: 4
Reputation: 4082
Physically clicking on the checkbox causes it to already be checked before the click event is triggered. Using jquery to click it runs the event code first. Using the change event instead will give you the desired results.
See working example below.
Upvotes: 1
Reputation: 301
Use the onchange event instead of the onclick:
The onclick event is fired when the box gets clicked BEFORE the value of the box is changed.
The workflow is like this: you click on you mouse => OnClick event is fired => checkbox gets ticked => OnChange event is fired
Upvotes: 2
Reputation: 76910
You could do:
function alertState(el){
if(el.prop("checked") === true) {
alert ("checked");
}
else{
alert ("not checked");
}
}
$('#chk').click(function() {
alertState($(this));
});
$("[id$=btn_on]").click(function () {
$('#chk').prop('checked', true);
alertState($('#chk'));
});
$("[id$=btn_off]").click(function () {
$('#chk').removeProp('checked');
alertState($('#chk'));
});
fiddle here http://jsfiddle.net/FCrSg/9/
Upvotes: 0
Reputation: 29434
I found this answer on Stack Overflow which creates manually an event and sends it.
You can put it into a function and call it from your click events:
function simulateClick(target)
{
var e = document.createEvent('MouseEvents');
e.initEvent( 'click', true, true );
target.dispatchEvent(e);
}
$("[id$=btn_on]").bind("click", function() {
simulateClick($('#chk')[0]);
});
$("[id$=btn_off]").click(function() {
simulateClick($('#chk')[0]);
});
Try it here: http://jsfiddle.net/FCrSg/10/
Almost the same as what you wanted on MDN: https://developer.mozilla.org/en/DOM/dispatchEvent_example
Upvotes: 0
Reputation: 50982
Try to use setTimeout which will wait a bit and then check it. The problem is that event triggers even faster than checkbox is switched for unknown reason.
$('#chk').click(function() {
var $this = $(this);
setTimeout(function() {
if ($this.prop("checked") === true) {
alert("checked");
}
else {
alert("not checked");
}
}, 10);
});
$("[id$=btn_on]").click(function() {
$('#chk').click();
});
$("[id$=btn_off]").click(function() {
$('#chk').click();
});
Upvotes: 2