I am trying to create a function on my website so that users can click a "save" button on a particular row of this table that will pull up the innerHtml of the entire row element that they have selected and then Im going to put that info into another page for them as their saved hiking trails.
I have been trying to do this by adding click event listeners to the tables and then accessing the information of the table row through the target.
Does anyone know how I can access the inner html of the whole row and not just the cell that the save button is in?
Here is my html
<table >
<tr>
<th>Trails</th>
<th>Province</th>
<th>Country</th>
</tr>
<tr>
<td >Lion's Head</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Pipe Track</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Skeleton Gorge</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Table Mountain</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >King Fisher Trail</td>
<td >Western Cape</td>
<td >South Africa<button id="save" button >Save</button></td>
</tr>
<tr>
<td >Robberg Peninsula</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Diep Walle Forest Walk</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
</table>
And here is the javascript that I have tried to use to target the row that I need.
const save = document.querySelector(".save");
console.log(save);
save.addEventListener("click", (e) => {
let row = document.getElementsByClassName("tableRow");
console.log(row[1], row[2], row[3]);
});
This javascript is not targeting the right table cells.
Any advice is appreciated! Thanks!
CodePudding user response:
You can't give same id's to different elements in DOM but you can create your custom attributes. I created button-id
for each button. Then used it to get the row that is clicked.
const save = document.querySelectorAll(".save"); // select all the buttons
const rows = document.querySelectorAll("tr") // select all the rows
console.log(rows)
save.forEach((btn) => {
btn.addEventListener("click", (e) => {
let id = e.target.getAttribute('button-id') // get the clicked buttons id
console.log(id)
console.log(rows[id]) // with id select the row
});
})
<table >
<tr>
<th>Trails</th>
<th>Province</th>
<th>Country</th>
</tr>
<tr>
<td >Lion's Head</td>
<td >Western Cape</td>
<td >South Africa<button button-id="1" >Save</button></td>
</tr>
<tr>
<td >Pipe Track</td>
<td >Western Cape</td>
<td >South Africa<button button-id="2" >Save</button></td>
</tr>
<tr>
<td >Skeleton Gorge</td>
<td >Western Cape</td>
<td >South Africa<button button-id="3" >Save</button></td>
</tr>
<tr>
<td >Table Mountain</td>
<td >Western Cape</td>
<td >South Africa<button button-id="4" >Save</button></td>
</tr>
<tr>
<td >King Fisher Trail</td>
<td >Western Cape</td>
<td >South Africa<button button-id="5" button >Save</button></td>
</tr>
<tr>
<td >Robberg Peninsula</td>
<td >Western Cape</td>
<td >South Africa<button button-id="6" >Save</button></td>
</tr>
<tr>
<td >Diep Walle Forest Walk</td>
<td >Western Cape</td>
<td >South Africa<button button-id="7" >Save</button></td>
</tr>
</table>
CodePudding user response:
First of all you have to assign the eventListener to all save buttons. After trigger by a click you have access to it by using the event.target function. Then you can go upwards to the parent element tr
. Afterwards you can handle the tr element.
Note It would be better to use event.target.closest('tr')
to avoid some collisions in the future. If same changes in the code will come. See the comment from @connexo
const save = document.querySelectorAll(".save");
save.forEach(s => {
s.addEventListener("click", (e) => {
const row = e.target.parentNode.parentNode;
row.classList.toggle('border');
console.log(row)
//
});
});
.border {
background: red;
}
<table >
<tr>
<th>Trails</th>
<th>Province</th>
<th>Country</th>
</tr>
<tr>
<td >Lion's Head</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Pipe Track</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Skeleton Gorge</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Table Mountain</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >King Fisher Trail</td>
<td >Western Cape</td>
<td >South Africa<button id="save" button >Save</button></td>
</tr>
<tr>
<td >Robberg Peninsula</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
<tr>
<td >Diep Walle Forest Walk</td>
<td >Western Cape</td>
<td >South Africa<button id="save" >Save</button></td>
</tr>
</table>
CodePudding user response:
You cannot have more than one element in your page with id="save"
- id must be unique at all times, per-document. For multiple elements, use a class instead.
That being said, use event.target.closest
to find the row from a delegate listener (that is, you install the click listener on an ancestor element and capitalize on the bubbling mechanism of events). This way you also only need one listener.
const table = document.getElementById('myTable');
table.addEventListener("click", (event) => {
if (event.target.matches('button.save')) {
const row = event.target.closest('tr');
console.log(row.innerText);
}
});
<table id="myTable">
<thead>
<tr>
<th>Trails</th>
<th>Province</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td >Lion's Head</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
<tr>
<td >Pipe Track</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
<tr>
<td >Skeleton Gorge</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
<tr>
<td >Table Mountain</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
<tr>
<td >King Fisher Trail</td>
<td >Western Cape</td>
<td >South Africa<button button >Save</button></td>
</tr>
<tr>
<td >Robberg Peninsula</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
<tr>
<td >Diep Walle Forest Walk</td>
<td >Western Cape</td>
<td >South Africa<button >Save</button></td>
</tr>
</tbody>
</table>