I will have this button once for each table (about 25
distinct tables) on this page and I'm hoping to find a way to have the onclick
event call the function constructDataValueString
and pass in the id
of the parent table (so that I don't have to explicitly reference the table id).
Is there a way to write:
onclick="constructDataValueString(*id_of_parent_table*)"
Graphical example of the HTML markup:
I will have this button once for each table (about 25
distinct tables) on this page and I'm hoping to find a way to have the onclick
event call the function constructDataValueString
and pass in the id
of the parent table (so that I don't have to explicitly reference the table id).
Is there a way to write:
onclick="constructDataValueString(*id_of_parent_table*)"
Graphical example of the HTML markup:
Share Improve this question edited Jan 23, 2019 at 4:45 Shidersz 17.2k2 gold badges27 silver badges51 bronze badges asked Jan 23, 2019 at 3:11 hatchetaxesawhatchetaxesaw 1831 gold badge3 silver badges13 bronze badges 05 Answers
Reset to default 4You can use closest(), for example:
onclick="constructDataValueString(this.closest('table').id)"
Example
const constructDataValueString = (id) => console.log("table id is: ", id);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:50% !important;}
<table id="populationbyage" border="2">
<thead>TABLE</thead>
<tbody>
<tr>
<td>
Some Cell...
</td>
<td>
<button onclick="constructDataValueString(this.closest('table').id)">
Copy
</button>
</td>
</tr>
</tbody>
</table>
Sure - use this.parentNode.parentNode.parentNode.parentNode.id
:
function constructDataValueString(id) {
console.log(id);
}
<table id="populationbyage">
<tbody>
<tr>
<td>
<button onclick="constructDataValueString(this.parentNode.parentNode.parentNode.parentNode.id)">Copy</button>
</td>
</tr>
</tbody>
</table>
(The above is a minimalistic example - it follows the exact same structure, it just has only the necessary elements and attributes required.
To ensure your internal table
structure can change without affecting this part, you could use this.closest("table")
so that you get the first parent <table>
element, from where you can get the id:
constructDataValueString(this.closest("table").id)
A more flexible solution
function parent(el, selector) {
var matchesFn;
// find vendor prefix
['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'].some(function (fn) {
if (typeof document.body[fn] == 'function') {
matchesFn = fn;
return true;
}
return false;
});
var parent;
// traverse parents
while (el) {
parent = el.parentElement;
if (parent && parent[matchesFn](selector)) {
return parent;
}
el = parent;
}
return null;
}
<table id="populationbyage">
<tbody>
<tr>
<td>
<button onclick="console.log(parent(event.target, '#populationbyage'))">Copy</button>
</td>
</tr>
</tbody>
</table>
As other answers suggest, use closest() https://developer.mozilla/en-US/docs/Web/API/Element/closest
To answer your question and also to address someone who wants a particular element to be sent, there is a way to exactly send the id of the table or any tag which you want.
`<table id="populationbyage" border="2">
<thead>TABLE</thead>
<tbody>
<tr>
<td>
Some Cell...
</td>
<td>
<button onclick="constructs(this.closest('#populationbyage').id)">
Copy
</button>
</td>
</tr>
</tbody>
</table>
<script>
function constructs(id) {
console.log(id)
}
</script>
`
The fetching of the id approach will pinpoint to the table you want to access here. It will help you to ignore all the nested tables if in future you wish to add some.