I am using jQuery's event delegation to add a click event to table rows. I also have a checkbox in the first td of the row. When I click anywhere in the row everything works as expected. However, I don't want the event to work when I click in the checkbox. I've tried using the :not() selector but perhaps I am missing something as I am still triggering the event when I click in the checkbox.
HTML
<tr>
<td>
<div class="myCheckbox"><input type="checkbox" name="userName" /></div>
</td>
<td><a href="/go/to/user/profile"></a></td>
<td>more info</td>
<td>more info</td>
<td>more info</td>
</tr>
jQuery
$('table tr:not(':checkbox')').on('click', 'td', function(event) {
// Do something
});
Can I get help fixing what I am attempting to do please?
Two options (both involve removing the tr:not
stuff from your existing code, which as you say doesn't work — tr
elements can't be checkboxes, and :not
checks the element, not its contents):
Add an event handler to the checkbox that calls e.stopPropagation
. Then the click event won't reach the row. You can do that either directly or via delegation. Here's a live example going direct. If you go indirect, be sure to test clicking label
s that activate the checkbox (if you're going to have them) on all of the browsers you intend to support.
or
Add this to your handler:
if ($(event.target).is('input[type=checkbox]')) {
return;
}
E.g.:
$('table').on('click', 'td', function(event) {
if ($(event.target).is('input[type=checkbox]')) {
return;
}
// Logic here
});
That works by testing the source of the event to see if it's a checkbox, and bailing early.
In both cases, if you use a label
to activate the checkbox, you may need to do the same thing for the label.
I got curious about what #2 would look like handling label
s, and it turns out it's enough code to move into a function, but not hard &mdash probably how I'd go: Live example | source
jQuery(function($) {
// The table cell click handler
$("table").on("click", "td", function(e) {
// Is the source a checkbox or the label for
// one?
if (isCheckbox($(e.target))) {
return;
}
// Normal handling
$(this).toggleClass("foo");
});
// Function to test whether the source is a
// checkbox, or the label of a checkbox
function isCheckbox($elm) {
var chkid;
if ($elm.is("input[type=checkbox]")) {
return true;
}
if ($elm.is("label")) {
chkid = $elm.attr("for");
if (chkid) {
return $("#" + chkid).is("input[type=checkbox]");
}
return !!$elm.find("input[type=checkbox]")[0];
}
return false;
}
});