7

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?

Andy F
  • 1,517
  • 2
  • 20
  • 35
  • What are you trying to get out of this? Having an "on/off" button for a `checkbox` seems a bit redundant. – Jack Oct 24 '11 at 13:41
  • 1
    @Jack, it's a very simplified example. I have a click listener on multiple checkboxes and a button to check all of them at once, hence why I need to know that the check action happens before the click code. – Andy F Oct 24 '11 at 13:45

7 Answers7

4

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

Adam Terlson
  • 12,610
  • 4
  • 42
  • 63
Blem
  • 796
  • 16
  • 36
2

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.

Working fiddle

$('#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();
});
genesis
  • 50,477
  • 20
  • 96
  • 125
2

Use the onchange event instead of the onclick:

http://jsfiddle.net/FCrSg/8/

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

paic_citron
  • 301
  • 2
  • 4
  • I don't think that workflow is correct. When you click the checkbox with the mouse it registers as checked when the onclick code runs. It doesn't do this when you call the click method in the code. But you and Blem are both right about the change event. – Andy F Oct 24 '11 at 13:48
1

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.

http://jsfiddle.net/FCrSg/3/

Maxx
  • 3,925
  • 8
  • 33
  • 38
1

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.

Tom
  • 4,910
  • 5
  • 33
  • 48
0

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

Community
  • 1
  • 1
ComFreek
  • 29,044
  • 18
  • 104
  • 156
0

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/

Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192