Skip to content
Advertisement

Get cell Value of Table html

I have this code (opt1) to get the text of the cell, which is clicked, but this alerts all of the objects in the table as its in a loop. But when I place it outside the loop I just get a random text from the table and not the one which is clicked (opt2).

I need the textContent of the cell, which is clicked, once, and not any other.

FYI: the cell contains multiple <td> inside <tr>.

The current method gets me the name text either of all cells (opt1) or the last cell (opt2)

HTML:

<table id="table">

        <tr class="cell" onclick="RowHandlers()">
            <td class="name">Name</td>
            <td class="date">Date</td>
            <td class="subject">Subject</td>

        </tr>

    </table>

opt1

function RowHandlers() {
    var table = document.getElementById("table");
    var name;
    for (var i=1;i<table.rows.length;i++) {

        name = table.rows[i].cells[0].innerText;

        alert(name);
    }
   
}

opt2

function RowHandlers() {
    var table = document.getElementById("table");
    var name;
    for (var i=1;i<table.rows.length;i++) {

        name = table.rows[i].cells[0].innerText;

       
    }
    alert(name);
}

Advertisement

Answer

Your problem seems to be identifying the clicked row after a click has happened.

We can solve this in multiple ways:

  1. In JS, use the event object‘s target property:
    1. (Preferred) Add handler via addEventListener().
      1. Use a single handler by making use of event propagation.
      2. Add handlers to each row.
    2. (Discouraged) Add handler via onevent property. Only one handler can be added this way.
    3. (Deprecated) Use the global object window.event.
  2. (Discouraged) In HTML, use inline event onclick on each row:
    1. Pass this to the handler function (e.g. <tr onclick="RowHandler(this)">). this in inline events will refer to the clicked element.
    2. Add IDs to each row (e.g. <tr id="row1">). For each row, pass its ID to the function (e.g. onclick="RowHandler('row1')"). Search for the element by the passed ID.

Using addEventListener()

To add a listener, pass the event type and the listener:

const input = document.querySelector("input");
const button = document.querySelector("button");

button.addEventListener("click", clickHandler);

function clickHandler(event) {
  console.log(input.value);
  input.value = "";
}
<input><button>Click me!</button>

Event propagation

Because events bubble up the DOM, <table>‘s listener will also fire when its rows are clicked. We can use event.target to get the event’s origin element and find the clicked row:

const table = document.querySelector("table");
table.addEventListener("click", tableClickHandler);

function tableClickHandler(event) {
  const row = event.target.closest("tr.cell"); // event.target may be a <td>
  
  const isInRow = Boolean(row);
  const isFirstRow = row === table.rows[0];
  if (!isInRow || isFirstRow) return;
  
  const name = row.cells[0].textContent;
  const date = row.cells[1].textContent;
  const subject = row.cells[2].textContent;
  
  console.log("Clicked:", { name, date, subject });
}
table,td{border:1px solid}
<table>
  <tr>
    <th>Name</th>
    <th>Date</th>
    <th>Subject</th>
  </tr>
  <tr class="cell">
    <td class="name">Some name</td>
    <td class="date">01-01-1999</td>
    <td class="subject">Some subject</td>
  </tr>
  <tr class="cell">
    <td class="name">Another name</td>
    <td class="date">02-02-2020</td>
    <td class="subject">Another subject</td>
  </tr>
</table>

Regarding your solutions

You are missing some way of identifying the clicked element; see my suggestions above.

In opt2, you are looping through all rows, but constantly overriding the variable name before using it. Therefore it is the same as only reading the name of the last row.

You may want to use .textContent over .innerText, because it doesn’t cause a reflow. If visibility of the content matters, choose .innerText, otherwise .textContent.

A table usually consists of sections (e.g. <thead>, <tbody>, <tfoot>, or an implicit section). Each section consists of rows; each row consists of cells. Therefore, your class name "cell" for a row may be confused with actual table cells (<td>/<th>).

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement