Suppose onclick handler is set for a <tr>
is it possible to disable/overwrite it for one particular <td>
?
<tr onclick='somefunction()'>
<td> </td> <!--onclick should work here-->
...
<td> </td> <!--onclick should not work here-->
...
<td> </td> <!--onclick should work here-->
</tr>
Of course I can set it for each <td>
separately or pass the name of a td
to the function and decide what to do based on this name, but it seems like there should be a simpler solution.
Suppose onclick handler is set for a <tr>
is it possible to disable/overwrite it for one particular <td>
?
<tr onclick='somefunction()'>
<td> </td> <!--onclick should work here-->
...
<td> </td> <!--onclick should not work here-->
...
<td> </td> <!--onclick should work here-->
</tr>
Of course I can set it for each <td>
separately or pass the name of a td
to the function and decide what to do based on this name, but it seems like there should be a simpler solution.
- You could add a class to that td, and check for in your function, and not do anything if it has it. – Matt Evanoff Commented Feb 1, 2015 at 10:12
4 Answers
Reset to default 10I found the easiest was to stop the event being passed to the parent html using onclick=event.stopPropagation() in the <td>
tag.
So <td class=whatever onclick=event.stopPropagation()>cell data<td>
In somefunction
you could check the cellIndex
of the td
, and return early, if a non-clickable cell has been clicked. Something like this:
function somefunction (e) {
if (e.target.cellIndex === 1) {return;}
/* Do something, the td is clickable */
}
To get this work with an inline handler, you've to pass the event object:
<tr onclick='somefunction(event)'>
A live demo at jsFiddle.
Things will get a bit more complex, if you've elements within cells. In that case you have to find a td
parent element, like so:
function somefunction (e) {
var target = e.target; // Cache the target element
while (target) { // Iterate through elements
if (target.tagName === 'TD') { // TD found, stop iteration
break;
}
target = target.parentElement; // Set target as a parent element of the current element
}
if (target === null) {return;} // Check that we really have a TD
if (target.cellIndex === 1) {return;} // A non-clickable cell clicked
:
}
A live demo at jsFiddle.
Edit 2018
In 2018 elements have closest()
method, hence the loop above is not needed, target = e.target.closest('td')
will make sure a td
is used.
A very simple way would be to use CSS pointer-events: none
, but unfortunately this doesn't work in FF in this particular case in IE<11 at all, though works well in Chrome and IE11. Also preventing pointer events would be bad, if the cell happens to contain interactive elements.
A live demo at jsFiddle.
EDIT:-
Try something like this.
HTML:
<tr id="row">
<td> </td> <!--onclick should work here-->
...
<td class="noChange"> </td> <!--onclick should not work here-->
...
<td> </td> <!--onclick should work here-->
</tr>
JavaScript:
window.onload = function() {
var row = document.getElementById("row");
for (i=0; i<row.childNodes.length; i++) {
if (row.childNodes[i].class != "noChange") {
row.childNodes[i].onclick="doStuff()";
}
}
}
<html>
<body>
<table border="1">
<tr onclick='somefunction(this)'>
<td><input type="text"></td> <!--onclick should work here--> ...
<td><input type="text"></td> <!--onclick should not work here--> ...
<td><input type="text"></td> <!--onclick should work here-->
</tr>
</table>
<script>
function somefunction(element) {
var td = element.children;
console.log(td);
var inputObj = td[1].children;
console.log(inputObj[0]);
inputObj[0].disabled = true;
}
</script>
</body>
</html>
The children property 'element.children' returns a list of an element's child elements, as an HTMLCollection object. enjoy :)