Steve Walsh
Steve Walsh

Reputation: 6645

Removing jquery click event handler from child elements of a table row

I have a table with a checkbox on the first column. When I click anywhere on the row, a class 'row_selected' is set on the table row and the checkbox is checked. The code is as follows:

$('#my_table > tbody > tr > td').live('click', function() {
    if ($(this).parent().hasClass('row_selected')) {
        $(this).parent().removeClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", false)
    } else {
        $(this).parent().addClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", true)
    }
})

The problem is some of the table cells have buttons which if clicked, I do not want the row to become selected. i.e.

<tr>
    <td class="checkbox">
        <input type="checkbox" checked="false"/>
    </td>
    <td>blah<td>
    <td>
        <a class="myButton">do stuff</a>
    </td>
    <td>blah<td>
</tr>

I want the jquery click event to work except when I click on myButton.

Anybody got any ideas?

Upvotes: 2

Views: 3703

Answers (3)

Matt Klooster
Matt Klooster

Reputation: 767

I do it by getting the event source at the start of the method and returning if it's not what I was expecting. For example

function getEventSrc(e)
{
    var eventIsFiredFromElement = e.target;
    if(eventIsFiredFromElement==null)
    {
        // I.E.
        eventIsFiredFromElement = e.srcElement;
    }
    return(eventIsFiredFromElement.type);
}

Returns what type of element was clicked. Looks like you want to stop if it's a button.

$('#my_table > tbody > tr > td').live('click', function(ev) {
    // Make sure event is not comming from a button.
    if(getEventSrc(ev) == 'button'){return;}

    if ($(this).children('a.myButton').length) return true; // prevents click on link
    if ($(this).parent().hasClass('row_selected')) {
        $(this).parent().removeClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", false)
    } else {
        $(this).parent().addClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", true)
    }
})

Upvotes: 1

Guilherme David da Costa
Guilherme David da Costa

Reputation: 2368

$('#my_table > tbody > tr > td').live('click', function() {
    if ($(this).children('a.myButton').length) return true; // prevents click on link
    if ($(this).parent().hasClass('row_selected')) {
        $(this).parent().removeClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", false)
    } else {
        $(this).parent().addClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", true)
    }
})

Where you try to find a link inside your td and if it finds it will return true so the link will continue working. (return false if you don't want the link to be performing the "click" action)

Created a simple example on jsFiddle.

Although you could use .stopPropagation if you change .live to .on

$('a.myButton').click(function(e) {
    e.stopPropagation();
});​

$('#my_table > tbody > tr > td').on('click', function() {
    if ($(this).parent().hasClass('row_selected')) {
        $(this).parent().removeClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", false)
    } else {
        $(this).parent().addClass('row_selected')
        $('td.checkbox input', this.parentNode).prop("checked", true)
    }
})

Here you can see a different example where .stopPropagation works without using .live. It will work only with jQuery1.7+

Upvotes: 1

j08691
j08691

Reputation: 207900

Couldn't you just stop propagation on the myButton class elements?

$('a.myButton').click(function(e) {
    e.stopPropagation();
});​

Here's a simplified jsFiddle example using your code that shows how the td click triggers work except when clicking the link.

Upvotes: 5

Related Questions