user80978
user80978

Reputation:

Adding an onclick event to a table row

I'm trying to add an onclick event to a table row through Javascript.

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        row = table.rows[i];
        row.onclick = function(){
                          var cell = this.getElementsByTagName("td")[0];
                          var id = cell.innerHTML;
                          alert("id:" + id);
                      };
    }
}

This works as expected in Firefox, but in Internet Explorer (IE8) I can't access the table cells. I believe that is somehow related to the fact that "this" in the onclick function is identified as "Window" instead of "Table" (or something like that).

If I could access the the current row I could perform a getElementById in the onclick function by I can't find a way to do that. Any suggestions?

Upvotes: 44

Views: 352273

Answers (12)

Swiler
Swiler

Reputation: 29

I try to figure out how to get a better result with pure JS and i get something this:

DEMO: https://jsfiddle.net/f5r3emjt/1/

const tbody = document.getElementById("tbody");
let rowSelected;

tbody.onclick = (e) => {
  for (let i = 0; i < e.path.length; ++i) {
    if (e.path[i].tagName == "TR") {
      selectRow(e.path[i]);
      break;
    }
  }
};

function selectRow(r) {
  if (rowSelected !== undefined) rowSelected.style.backgroundColor = "white";

  rowSelected = r;
  rowSelected.style.backgroundColor = "dodgerblue";
}

And now you can use the variable rowSelected in other function like you want or call another function after set the style

I like more this implementacion and also compatible with any browser

tbody.onclick = (e) => {
 // we need to get the tr element because we always select the td element
 const tr = e.srcElement.parentNode; 
 tr == "TR" && selectRow( tr );
};

Upvotes: 1

SouMitya chauhan
SouMitya chauhan

Reputation: 331

selectRowToInput();
function selectRowToInput(){
var table = document.getElementById("table");
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++)
{
    var currentRow = table.rows[i];
    currentRow.onclick = function() {

       rows=this.rowIndex;
        console.log(rows);  
    };
}

}

Upvotes: 0

Cornelius
Cornelius

Reputation: 1

While most answers are a copy of SolutionYogi's answer, they all miss an important check to see if 'cell' is not null which will return an error if clicking on the headers. So, here is the answer with the check included:

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        // check if not null
        if(!cell) return; // no errors! 
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}

Upvotes: 0

Zolfaghari
Zolfaghari

Reputation: 1323

Simple way is generating code as bellow:

<!DOCTYPE html>
<html>
<head>

<style>
  table, td {
      border:1px solid black;
  }
</style>

</head>
<body>
<p>Click on each tr element to alert its index position in the table:</p>
<table>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
  <tr onclick="myFunction(this)">
    <td>Click to show rowIndex</td>
  </tr>
</table>

<script>
  function myFunction(x) {
      alert("Row index is: " + x.rowIndex);
  }
</script>

</body>
</html>

Upvotes: 12

SolutionYogi
SolutionYogi

Reputation: 32223

Something like this.

function addRowHandlers() {
  var table = document.getElementById("tableId");
  var rows = table.getElementsByTagName("tr");
  for (i = 0; i < rows.length; i++) {
    var currentRow = table.rows[i];
    var createClickHandler = function(row) {
      return function() {
        var cell = row.getElementsByTagName("td")[0];
        var id = cell.innerHTML;
        alert("id:" + id);
      };
    };
    currentRow.onclick = createClickHandler(currentRow);
  }
}

EDIT

Working demo.

Upvotes: 56

user3121053
user3121053

Reputation: 31

Here is how I do this. I create a table with a thead and tbody tags. And then add a click event to the tbody element by id.

<script>
    document.getElementById("mytbody").click = clickfunc;
    function clickfunc(e) {
        // to find what td element has the data you are looking for
        var tdele = e.target.parentNode.children[x].innerHTML;
        // to find the row
        var trele = e.target.parentNode;
    }
</script>
<table>
    <thead>
        <tr>
            <th>Header 1</th>
            <th>Header 2</th>
        </tr>
    </thead>
    <tbody id="mytbody">
        <tr><td>Data Row</td><td>1</td></tr>
        <tr><td>Data Row</td><td>2</td></tr>
        <tr><td>Data Row</td><td>3</td></tr>
    </tbody>
</table>

Upvotes: 3

robertocm
robertocm

Reputation: 132

I was trying to select a table row, so that it can be easily copied to the clipboard and then pasted in Excel. Below is a small adaptation of your solution.

References:

<!DOCTYPE html>
<html>
<body>

<div>
    <table id="tableId" border=1>
      <tbody>
        <tr><td>Item <b>A1</b></td><td>Item <b>B1</b></td></tr>
        <tr><td>Item <b>A2</b></td><td>Item <b>B2</b></td></tr>
        <tr><td>Item <b>A3</b></td><td>Item <b>B3</b></td></tr>
      </tbody>
    </table>
</div>

<script>
function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
            function(row) 
            {
                return function() { 
                                        var cell = row.getElementsByTagName("td")[0];
                                        var id = cell.innerHTML;

                                        var cell1 = row.getElementsByTagName("td")[1];
                                        var id2 = cell1.innerHTML;
                                        // alert(id + " - " + id2);
                                        window.prompt("Copy to clipboard: Ctrl+C, Enter", "<table><tr><td>" + id + "</td><td>" + id2 + "</td></tr></table>")
                                 };
            };

        currentRow.onclick = createClickHandler(currentRow);
    }
}
window.onload = addRowHandlers();
</script>
</body>
</html> 

Upvotes: 0

Alexander Bell
Alexander Bell

Reputation: 7918

Here is a compact and a bit cleaner version of the same pure Javascript (not a jQuery) solution as discussed above by @redsquare and @SolutionYogi (re: adding onclick event handlers to all HTML table rows) that works in all major Web Browsers, including the latest IE11:

function addRowHandlers() {
    var rows = document.getElementById("tableId").rows;
    for (i = 0; i < rows.length; i++) {
        rows[i].onclick = function(){ return function(){
               var id = this.cells[0].innerHTML;
               alert("id:" + id);
        };}(rows[i]);
    }
}
window.onload = addRowHandlers();

Working DEMO

Note: in order to make it work in IE8 as well, instead of this pointer use the explicit identifier like function(myrow) as suggested by @redsquare. Best regards,

Upvotes: 4

Fco Javier Rod Ca
Fco Javier Rod Ca

Reputation: 79

My table is in another iframe so i modified SolutionYogi answer to work with that:

<script type="text/javascript">
window.onload = addRowHandlers;
function addRowHandlers() {
    var iframe = document.getElementById('myiframe');
    var innerDoc = (iframe.contentDocument) ? iframe.contentDocument : iframe.contentWindow.document;

    var table = innerDoc.getElementById("mytable");
    var rows = table.getElementsByTagName("tr");
    for (i = 0; i < rows.length; i++) {
        var currentRow = table.rows[i];
        var createClickHandler = 
            function(row) 
            {
                return function() { 
                                        var cell = row.getElementsByTagName("td")[0];
                                        var id = cell.innerHTML;
                                        alert("id:" + id);
                                 };
            }

        currentRow.onclick = createClickHandler(currentRow);
    }
}
</script>

Upvotes: 0

Luke Rinard
Luke Rinard

Reputation: 313

Try changing the this.getElementsByTagName("td")[0]) line to read row.getElementsByTagName("td")[0];. That should capture the row reference in a closure, and it should work as expected.

Edit: The above is wrong, since row is a global variable -- as others have said, allocate a new variable and then use THAT in the closure.

Upvotes: 0

redsquare
redsquare

Reputation: 78667

Head stuck in jq for too long. This will work.

function addRowHandlers() {
    var table = document.getElementById("tableId");
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        var row = table.rows[i];
        row.onclick = function(myrow){
                          return function() { 
                             var cell = myrow.getElementsByTagName("td")[0];
                             var id = cell.innerHTML;
                             alert("id:" + id);
                      };
                  }(row);
    }
}

Upvotes: 1

Nick Riggs
Nick Riggs

Reputation: 1275

I think for IE you will need to use the srcElement property of the Event object. if jQuery is an option for you, you may want to consider using it - as it abstracts most browser differences for you. Example jQuery:

$("#tableId tr").click(function() {
   alert($(this).children("td").html());
});

Upvotes: 8

Related Questions