AnApprentice
AnApprentice

Reputation: 110960

How to bind to a click to toggle a checkbox?

Given a list of LIs each LI includes a checkbox like so:

<li class="contact">
    <input type="checkbox" class="checkbox" name="checkableitems[]" value="1333">
    <div class="content">
        <cite>Baby James</cite>
    </div>
</li>

I would like to be able to toggle the checkbox on LI click, not just on checkbox click. I got this work which you can see here:

http://jsfiddle.net/xgB5X/2/

The problem is, while clicking on the LI toggles the checkbox, click on the checkbox directly is no broken. Clicking on the checkbox no longer toggles. Any suggestions to get this working? Thanks

Upvotes: 0

Views: 352

Answers (6)

Musa
Musa

Reputation: 97672

Even though I think you should use a label for this here is method working

$('.listview li').bind({
  click: function(e) {
      var checkbox = $(this).find('.checkbox').get(0);
      if (e.target == checkbox) return;
      checkbox.click();
  }
});

FIDDLE

Upvotes: 1

Mark Pieszak - Trilon.io
Mark Pieszak - Trilon.io

Reputation: 66991

A couple of notes:

use .prop() instead of .attr() (it's also easier to tell true/false on it, must each other through all browsers.

You can check the e.srcElement for your classname of checkbox within the click().

$('.listview li').on('click', function(e) {

  if (e.srcElement.className === 'checkbox') {
      e.stopPropagation();   
      return;
  }

  checkbox = $(this).find(':checkbox');

   // Toggle Checkbox
   if (checkbox.prop('checked')) {
       checkbox.prop('checked', false);
   } else {
       checkbox.prop('checked', true);
   }

});

jsFiddle

Upvotes: 1

adeneo
adeneo

Reputation: 318222

$('.listview li').on('click', function(e) {
      var c = $('.checkbox', this);
      c.prop('checked', !c[0].checked);
}).find('.checkbox').on('click', function(e) {e.stopPropagation();});​​​​​

FIDDLE

Upvotes: 1

Ram
Ram

Reputation: 144689

Why not using label tags?

<li class="contact">
    <input id='input1' type="checkbox" class="checkbox" name="checkableitems[]" value="1333">
    <label for='input1'>Baby James</label>
</li>

DEMO

Upvotes: 4

Amin Eshaq
Amin Eshaq

Reputation: 4024

You can try something like this jsFiddle

$('.listview li > *').children().bind({
    click: function(e) {
        checkbox = $(this).closest('li').find('.checkbox');
        checkbox.attr('checked', !checkbox.is(':checked'));
    }
});​

Upvotes: 1

Vinayak Phal
Vinayak Phal

Reputation: 8919

http://jsfiddle.net/xgB5X/3/ Check this.

I've added a little bit of code to stop the propagation. This will prevent the event to reach to the li tag.

$('input[type=checkbox]').on('click', function(e) {
    e.stopPropagation();
});

Your problem was when the checkbox was clicked it was changing its state, but when the event reach to the li tag as it contains the check box once again it was changing its state.

Upvotes: 3

Related Questions