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?
This question is related to
javascript
html
dom
dom-events
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.
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());
});
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>
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>
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);
}
}
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);
};
}
}
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:
Where I took the window.prompt line from (Jarek Milewski):
The user is presented with the prompt box, where the text to be copied is already selected...
For selecting a complete table (Tim Down). Very interesting, but I was not able to adapt for a <tr>
element.
<!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>
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);
}
}
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,
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
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.
Simple way is generating code as bellow:
<!DOCTYPE html>_x000D_
<html>_x000D_
<head>_x000D_
_x000D_
<style>_x000D_
table, td {_x000D_
border:1px solid black;_x000D_
}_x000D_
</style>_x000D_
_x000D_
</head>_x000D_
<body>_x000D_
<p>Click on each tr element to alert its index position in the table:</p>_x000D_
<table>_x000D_
<tr onclick="myFunction(this)">_x000D_
<td>Click to show rowIndex</td>_x000D_
</tr>_x000D_
<tr onclick="myFunction(this)">_x000D_
<td>Click to show rowIndex</td>_x000D_
</tr>_x000D_
<tr onclick="myFunction(this)">_x000D_
<td>Click to show rowIndex</td>_x000D_
</tr>_x000D_
</table>_x000D_
_x000D_
<script>_x000D_
function myFunction(x) {_x000D_
alert("Row index is: " + x.rowIndex);_x000D_
}_x000D_
</script>_x000D_
_x000D_
</body>_x000D_
</html>
_x000D_
Source: Stackoverflow.com