Select Table Row (or Cell) WITHOUT Onclick

I have generated a table from custom settings data, and I want the user to select a table row to edit the settings data.

This generates the table from custom settings:

var tableRef = document.getElementById("customTagTable").id;
for (i = 0; i < Object.keys(customMenus).length; i++) {
    let row = customTagList.insertRow();
    let rowId = customMenus[i].menuId;
    row.setAttribute('id', rowId);

    var addCell = row.insertCell(0);
    var newText = document.createTextNode(customMenus[i].menuArg)
    addCell.appendChild(newText);
    var addCell = row.insertCell(0);
    var newText = document.createTextNode(customMenus[i].parentId)
    addCell.appendChild(newText);
    var addCell = row.insertCell(0);
    var newText = document.createTextNode(customMenus[i].menuTitle)
    addCell.appendChild(newText);
    var addCell = row.insertCell(0);
    var newText = document.createTextNode(customMenus[i].menuId)
    addCell.appendChild(newText);

And this hears the click, when the table body is clicked on:

customTagList.addEventListener("click", function(element) {
    let rows = customTagList.getElementsByTagName('tr');
    zzselection = customTagList.getSelectedItem;
    console.log("moo", rows);
    console.log(element.row);
    console.log(zzselection);

});

The basic table format is:

<table id="customTagTable" border=2>
    <thead id="customTableHead">
        <tr>
            <th>Menu ID</th>
            <th>Menu Title</th>
            <th>Parent ID</th>
            <th>Menu Argument</th>
        </tr>
    </thead>
    <tbody id="customTagList">
        <tr>
    </tbody>
</table>

I have been unable to programmatically get either the row id, or the index of the row without adding an onclick to the <tr> element, which throws a permission error.

I am under the impression that using onclick in an extension is frowned upon, so how would I get the row id or index?

There’s many paths to do this.

One is to add the event listeners in a loop over the table and pass them the location info down.

One is to have the location info on the table cell or row, so you can read it inside the event listener.

One is to search the table for the element that the listener was fired for and determine location information from that.

I think that I got it.

Warning, this is some seriously fugly code:


var tableRef = document.getElementById("customTagList").rows;
console.log(tableRef[1]);
for (i = 0; i < tableRef.length; i++) {
let singleRow = tableRef[i];
let singleRowId = tableRef[i].id;
//singleRowId = singleRow[i];
singleRow.addEventListener('click', () => {getMenuClicked(singleRowId);});
}

Wait, the ID you’re passing in is the one of the element that’s clicked? That is already available from within an event listener:

singleRow.addEventListener("click", function(event) {
  console.log(event.target.id);
});

Well, that’s a lot cleaner and easier.

Just be aware that event.target is the element that was actually targeted by the event (i.e. the one that was clicked), not the element you listen on.
In this case that is likely on of the cells or something they contain, not the row. This should always work:

table.addEventListener("click", event => {
  const row = event.target.closest('tr'); if (!row) return;
  console.log(row.id);
});

Note that a single listener higher up is actually enough.
(i’m not sure if Text nodes can be event.target. In that case, you may need to use (event.target.closest ? event.target : event.target.parentNode).closest('tr').)

OMG, where has this been all my life? (Well, I am a bit older than Firefox 35…)