0

I was asked to mark as checked the checkbox on the table line click, the script below is working but now when I click directly on the checkbox, it doesn't work, works only if I click the table line.

I have this html:

<tr class="linha_tela" id="4">
   <td>Profile</td>
   <td>Clientes</td>
   <td>
     <input type="checkbox" checked="checked" id="controller_4" name="controllers[]" value="4" />
  </td>
</tr>

And this is my script:

    $('.linha_tela').click(function(){
        var checkbox = $(this).find(':checkbox');
        checkbox.attr('checked', !checkbox.attr('checked'));
    });

Thanks

4 Answers 4

3

What's happening is that the checkbox is toggling when you click on it, then the event handler is triggered causing it to become unchecked. This is basically occurring instantaneously, which is why it appears to just not work at all.

Try this:

$('.linha_tela').click(function(event) {
    if (!$(event.target).is(':checkbox')) {
        var checkbox = $(this).find(':checkbox');
        checkbox.attr('checked', !checkbox.attr('checked'));
    }
});

Edit: Here's a jsfiddle demo of it working.

Sign up to request clarification or add additional context in comments.

4 Comments

this doesn't work :( i was going to suggest a similar solution, but haven't come up with one yet that works quite right.
@Patricia - see my edit. Note that I changed the reference of this to event.target.
nope. here's a js fiddle of your solution to play with : jsfiddle.net/Q6q46
wow, that's weird. something funny must have happened with my fiddles. b/c your right, this is pretty much the same as my answer now and maybe even a bit better :) certainly a better option then the accepted one. upvote
2

This is happening because the checkbox is in the table row, so when you are clicking it, it's changing it's status (because that's what checkboxes do).

Then the click is bubbling up to your tr, and running the script, which is changing it status back.

you need to check the event target, and if it's not an input, do your thing, if it is, then don't.

here's the modified script:

$('.linha_tela').click(function(event) {

    if (event.target.nodeName != 'INPUT') {
        var checkbox = $(this).find(':checkbox');
        checkbox.attr('checked', !checkbox.attr('checked'));
    }
});

and a link to a jsfiddle to try it out: http://jsfiddle.net/yDEyC/

Comments

1
$(":checkbox").click(function(event) {
  event.stopPropagation();
});

This should work.

1 Comment

This works, but it's adding complication since you now need two events when you're really just trying to add one.
1

Here is a jsfiddle that demonstrates your code scenario:

http://jsfiddle.net/sAfTT/

The problem you're running into is a common one with events in HTML. When events are fired, they are fired on every element to which they can be applied in order from closest to furthest away. This is called bubbling(theres also capturing which works in reverse). http://www.quirksmode.org/js/events_order.html

So, in reality, when you are clicking on the checkbox, you are also clicking on the row, so the handler call looks like this.(assuming the box is unchecked to start with. reverse check/uncheck as applicable)

  1. Checkbox clicked: check the box
  2. Can I bubble up? Yes
  3. Row clicked. Is there an event handler? Yes
  4. Fire event handler (yours). This determines if the checkbox is checked. It is.
  5. Because the box is checked, uncheck it.
  6. Can I bubble up? Yes
  7. Table Clicked. Is there an event handler? no
  8. Document Clicked. Is there an event handler? No.

you can attach an event handler to the checkbox directly to prevent bubbling

$(':checkbox').click(function(e){
    e.preventDefault();
    e.stopPropagation();
})​

edit: I could never get the prevent default to work just right in jsfiddle, but the concept provided by the other answers work nicely too.

1 Comment

thanks but with e.preventDefault(); it doesn't work even on my notebook, it's not a jsfiddle problem...

Your Answer

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