Javascript Onclick with Table Rows

I am having problems with my JScript code. I am trying to loop through all of the rows in a table and add an onclick event. I can get the onclick event to add but have a couple of problems.

The first problem is that all rows end up getting set up with the wrong parameter for the onclick event.

The second problem is that it only works in IE.

Here is the code excerpt...

shanesObj.addTableEvents = function(){
table = document.getElementById("trackerTable");
for(i=1; i<table.getElementsByTagName("tr").length; i++){
    row = table.getElementsByTagName("tr")[i];
    orderID = row.getAttributeNode("id").value;
    alert("before onclick: " + orderID);
    row.onclick=function(){shanesObj.tableRowEvent(orderID);};
}}

shanesObj.tableRowEvent = function(orderID){
alert(orderID);}

The table is located at the following location...

http://www.blackcanyonsoftware.com/OrderTracker/testAJAX.html

The id's of each row in sequence are... 95, 96, 94...

For some reason, when shanesObj.tableRowEvent is called, the onclick is set up for all rows with the last value id that went through iteration on the loop (94).

I added some alerts to the page to illustrate the problem.

Answers:

Answer

When a function is called in javascript, the first thing that happens is that the interpreter sets the scope chain to the state it was in when the function was defined. In your case the scope chain looks like:

   GLOBAL
     |
CAll addTableEvents 
     |
CALL onclick

So when the variable orderID is stumbled upon by the javascript interpreter it searches the scope chain for that variable. There is no orderID defined inside your onclick function, so the next spot to look is inside addTableEvents. You would think orderID is defined here, but since you did not declare orderID with the var keyword, orderID became a global variable, so orderID is not found inside addTableEvents. The last spot to look is inside GLOBAL, and sure enough it is there, and its value is the last one which it was assigned, and in this case its the last value of orderID = row.getAttributeNode("id").value; in the for loop.

To see this more clearly look at the following

shanesObj.addTableEvents = function(){
table = document.getElementById("trackerTable");
for(i=1; i<table.getElementsByTagName("tr").length; i++){
        row = table.getElementsByTagName("tr")[i];
        orderID = row.getAttributeNode("id").value;
        alert("before onclick: " + orderID);
        row.onclick=function(){var orderID = orderID; shanesObj.tableRowEvent(orderID);};
}
orderID = -1;
}

shanesObj.tableRowEvent = function(orderID){
alert(orderID);
}

The result of a click here will always be -1.

So, to get around this problem, I suggest you drop all the extra and unneeded code and use something like the following,

for(i=1; i<table.getElementsByTagName("tr").length; i++){
        row = table.getElementsByTagName("tr")[i];
        row.onclick=function(){shanesObj.tableRowEvent(this.id);};

}

Just access the id attribute directly from the called object.

P.S. I have no idea why your code doesn't work in IE (it worked in my IE7).

Answer

Why not attach the event handler to the table and grab the rowindex of the cell that fired the click event inside the click handler.

Answer

y'cant get much simpler than this!
can obviously be used with dynamically built rows.
lots of love,
sb.

<html>

<head>
<title></title>
<script language="JavaScript" type="text/javascript">
<!--
var TO,URL;
function Link(url){
 URL=url;
 TO=setTimeout('window.location=URL;',500);
}
//-->
</script>
</head>

<body>

<tr onclick="Link('anotherpage.html');">
<td>row1 cell1</td>
<td>row1 cell2</td>
</tr>

<tr onclick="Link('yetanotherpage.html');">
<td>row2 cell3</td>
<td>row2 cell4</td>
</tr>

</body>

</html>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.