160

I have the following:

<form id="myform">
   <input type="checkbox" name="check1" value="check1">
   <input type="checkbox" name="check2" value="check2">
</form>

How do I use jQuery to capture any check event occuring in myform and tell which checkbox was toggled (and know if it was toggled on or off)?

7 Answers 7

288
$('#myform :checkbox').change(function() {
    // this will contain a reference to the checkbox   
    if (this.checked) {
        // the checkbox is now checked 
    } else {
        // the checkbox is now no longer checked
    }
});
Sign up to request clarification or add additional context in comments.

8 Comments

this is already set to the checkbox's DOM element so this.checked is sufficient. You won't need to create another jQuery object for it unless you plan on manipulating it.
Just a small tip. You will get a performance boost by using input:checkbox in your selector instead of just :checkbox since the latter is translated to the universal selector *:checkbox.
Click is not anywhere close to any check event.
This is no way the best answer. If you have a corresponding label for your input (like <label for='myInput'>Checkbox:</label><input id='myInput' name='myInput' type='checkbox'/> ) and you click the label, the checkbox will be checked, but this function would NOT be called. You should use the .change() event
This answer does not fully provide the answer - please see Anurag's answer below, which is a MUCH more complete (and accurate) answer. This answer is partly correct of course, but as stated, it is not the best answer.
|
133

Use the change event.

$('#myform :checkbox').change(function() {
    // this represents the checkbox that was checked
    // do something with it
});

7 Comments

If the checkbox is hidden, then a user won't be able to interact with it. Let me know if you meant something else.
This does not fire for $("input[name=check1]").prop('checked', true). See jsfiddle.net/Z3E8V/2
That is by design. Programmatically changing a DOM element's property does not trigger associated event handlers. You'll have to fire them manually.
This should be the selected answer, it covers clicking a checkbox's label
From jQuery documentation: "Because :checkbox is a jQuery extension and not part of the CSS specification, queries using :checkbox cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use [type="checkbox"] instead."
|
58

There are several useful answers, but none seem to cover all the latest options. To that end all my examples also cater for the presence of matching label elements and also allow you to dynamically add checkboxes and see the results in a side-panel (by redirecting console.log).

  • Listening for click events on checkboxes is not a good idea as that will not allow for keyboard toggling or for changes made where a matching label element was clicked. Always listen for the change event.

  • Use the jQuery :checkbox pseudo-selector, rather than input[type=checkbox]. :checkbox is shorter and more readable.

  • Use is() with the jQuery :checked pseudo-selector to test for whether a checkbox is checked. This is guaranteed to work across all browsers.

Basic event handler attached to existing elements:

$('#myform :checkbox').change(function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/2/

Notes:

  • Uses the :checkbox selector, which is preferable to using input[type=checkbox]
  • This connects only to matching elements that exist at the time the event was registered.

Delegated event handler attached to ancestor element:

Delegated event handlers are designed for situations where the elements may not yet exist (dynamically loaded or created) and is very useful. They delegate responsibility to an ancestor element (hence the term).

$('#myform').on('change', ':checkbox', function () {
    if ($(this).is(':checked')) {
        console.log($(this).val() + ' is now checked');
    } else {
        console.log($(this).val() + ' is now unchecked');
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/4/

Notes:

  • This works by listening for events (in this case change) to bubble up to a non-changing ancestor element (in this case #myform).
  • It then applies the jQuery selector (':checkbox' in this case) to only the elements in the bubble chain.
  • It then applies the event handler function to only those matching elements that caused the event.
  • Use document as the default to connect the delegated event handler, if nothing else is closer/convenient.
  • Do not use body to attach delegated events as it has a bug (to do with styling) that can stop it getting mouse events.

The upshot of delegated handlers is that the matching elements only need to exist at event time and not when the event handler was registered. This allows for dynamically added content to generate the events.

Q: Is it slower?

A: So long as the events are at user-interaction speeds, you do not need to worry about the negligible difference in speed between a delegated event handler and a directly connected handler. The benefits of delegation far outweigh any minor downside. Delegated event handlers are actually faster to register as they typically connect to a single matching element.


Why doesn't prop('checked', true) fire the change event?

This is actually by design. If it did fire the event you would easily get into a situation of endless updates. Instead, after changing the checked property, send a change event to the same element using trigger (not triggerHandler):

e.g. without trigger no event occurs

$cb.prop('checked', !$cb.prop('checked'));

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/5/

e.g. with trigger the normal change event is caught

$cb.prop('checked', !$cb.prop('checked')).trigger('change');

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/6/

Notes:

  • Do not use triggerHandler as was suggested by one user, as it will not bubble events to a delegated event handler.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/8/

although it will work for an event handler directly connected to the element:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/u8bcggfL/9/

Events triggered with .triggerHandler() do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing.

Reference: http://api.jquery.com/triggerhandler/

If anyone has additional features they feel are not covered by this, please do suggest additions.

2 Comments

I discovered the .trigger('change') with this answer. Thanks for this very complete answer !
+1 on the delegated event handler on children. I actually need this for some complicated dynamic code and you just saved me allot of patchy coding that is far better suited for a parent element.
34

Using the new 'on' method in jQuery (1.7): http://api.jquery.com/on/

    $('#myform').on('change', 'input[type=checkbox]', function(e) {
        console.log(this.name+' '+this.value+' '+this.checked);

    });
  • the event handler will live on
  • will capture if the checkbox was changed by keyboard, not just click

3 Comments

This does not fire for $("input[name=check1]").prop('checked', true). See jsfiddle.net/Z3E8V/2
Just add .triggerHandler('change'); after the .prop call. Then it will toggle the box AND call the event.
an alternative: $(document).on('change','input[type="checkbox"]', function() { $('input[type="checkbox"]').not(this).prop('checked', false); });
6

Acknowledging the fact that the asker specifically requested jQuery and that the answer selected is correct, it should be noted that this problem doesn't actually need jQuery per say. If one desires to solve this problem without it, one can simply set the onClick attribute of the checkboxes that he or she wants to add additional functionality to, like so:

HTML:

<form id="myform">
  <input type="checkbox" name="check1" value="check1" onClick="cbChanged(this);">
  <input type="checkbox" name="check2" value="check2" onClick="cbChanged(this);">
</form>

javascript:

function cbChanged(checkboxElem) {
  if (checkboxElem.checked) {
    // Do something special
  } else {
    // Do something else
  }
}

Fiddle: http://jsfiddle.net/Y9f66/1/

1 Comment

Putting event handlers directly in the HTML works, of course. But it it is in direct conflict with DRY and progressive enhancement methodologies. A more accurate answer would be "You don't need jQuery to add event handlers" and instead, using standard JS to attach the click handlers in a seperate JS file rather than putting onclick attributes in the HTML. Doing so "works" but good coding practice dictates you should avoid it when possible (which is nearly always at this point unless you must support IE6 or something, which even MS says you shouldn't do anymore)
5
$('#myform input:checkbox').click(
 function(e){
   alert($(this).is(':checked'))
 }
)

1 Comment

val() does not tell you if checked is true.
4

I have try the code from first answer, it not working but I have play around and this work for me

$('#vip').change(function(){
    if ($(this).is(':checked')) {
        alert('checked');
    } else {
        alert('uncheck');
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.