Kieran Senior
Kieran Senior

Reputation: 18220

jQuery Click Stop Propagation

I have a simple setup, a table whose cells have checkboxes within them. I have two events, one that responds to clicking on the checkboxes and another which responds to clicking on the "tr" elements. When I click on a checkbox I don't want the table row event to fire. I've tried event.stopPropagation() and return false; without any luck. Here's a snippet:

$("tr").click(function() {
    alert("tr clicked");
});

$("input[type=checkbox]").change(function(event) {
    event.stopPropagation();
    alert("checkbox clicked");
});

With something like:

<tr>
    <td><input type="checkbox" id="something" name="something" /></td>
</tr>

If the change event fires the click event will also fire. Any clues on how to stop the tr click event from firing if the checkbox is changed within the td element of the tr?

Upvotes: 3

Views: 8176

Answers (4)

Šime Vidas
Šime Vidas

Reputation: 185883

I recommend this:

$( '#theTable' ).delegate( 'tr', 'click', function ( e ) {
    if ( $( e.target ).is( 'input:checkbox' ) ) { 
        alert( 'checkbox clicked' );
    } else {
        alert( 'tr clicked' );
    }        
});

So, you have only one click handler for the entire table.

Btw, you don't have to place all the code inside this one handler. You can have separate functions for each action (checkbox clicked VS row clicked), and then...

$( '#theTable' ).delegate( 'tr', 'click', function ( e ) {
    if ( $( e.target ).is( 'input:checkbox' ) ) { 
        checkboxClicked( e );
    } else {
        rowClicked( e );
    }        
});

function checkboxClicked ( e ) {
    // process event
}

function rowClicked ( e ) {
    // process event
}

Upvotes: 5

Muhammad Usman
Muhammad Usman

Reputation: 12503

Use click instead of change. Seems to be working here http://jsfiddle.net/usmanhalalit/mGVv7/1/

$("input[type=checkbox]").click(function(event) {
    event.stopPropagation();
    alert("checkbox clicked");
});

Upvotes: 1

Alnitak
Alnitak

Reputation: 339786

You need to catch the .click() event on the checkbox, not the .change() event.

By the time .change() is fired the click event has already been processed and bubbled back up the DOM to the parent elements.

Upvotes: 0

Jens Roland
Jens Roland

Reputation: 27770

The problem is that .change and .click are different events firing at different times during an action on a checkbox, so the handler for one can't affect the other. You could add a check in your click handler:

$("tr").click(function(event) {
  if (event.target.type == 'checkbox') return;
  alert("tr clicked");
});

$(":checkbox").change(function(event) {
  alert("checkbox clicked");
});

Or use the .click event for both handlers:

$("tr").click(function(event) {
  alert("tr clicked");
});

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

Upvotes: 0

Related Questions