'js vanilla on click delegate on tr of a table
I'm trying to find on click a data attribute from the tr element of a table with the delegated click event, but it doesn't return anything, what am I wrong?
I made a fiddle to try and test
document.querySelector('table#listaCar tbody').addEventListener('click', e => {
if (e.target.matches(".car-item")) {
alert(e.target.getAttribute('data-id-car'));
}
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>
Solution 1:[1]
e.target is the td, not the tr.
Easiest solution is to use .parentNode to get the td's parent: the tr then you can test using matches and get the data attribute as desired
const tr = e.target.parentNode;
if (tr.matches(".car-item")) {
alert(tr.getAttribute('data-id-car'));
}
document.querySelector('table#listaCar tbody').addEventListener('click', e => {
const tr = e.target.parentNode;
if (tr.matches(".car-item")) {
alert(tr.getAttribute('data-id-car'));
}
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>
Solution 2:[2]
You need to do a test on the element click to see if it is a table cell (TD) and if it is grab the parent.
In my example I am looping through all the rows to apply the click.
document.querySelectorAll('.car-item').forEach(item => {
item.addEventListener('click', e => {
let el = e.target.tagName === "TD" ? e.target.parentElement : e.target;
alert(el.getAttribute('data-id-car'));
});
});
table#listaCar tbody tr {
cursor: pointer;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="listaCar" class="table table-bordered table-hover bg-white">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Status</th>
<th scope="col">Date</th>
<th scope="col">N. IUV</th>
</tr>
</thead>
<tbody>
<tr data-id-car="4140" class="car-item">
<td>4140</td><td>TO PAY</td><td>13-05-2022</td><td>10</td>
</tr>
<tr data-id-car="4129" class="car-item">
<td>4129</td><td>TO PAY</td><td>12-05-2022</td><td>15</td>
</tr>
</tbody>
</table>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | 0stone0 |
| Solution 2 | Pi and Mash |
