0

I have a dynamically generated table that works great except for the onclick event. I put the result to an alert so you can see. I was expecting it to show the correct value of var i at each iteration, but each iteration shows the same value of 3 each time, instead of 0, 1, 2 like I would expect it to. Am I doing something wrong, or is there a better way to implement an onclick event?

NOTE: No jquery please

<html>
<head></head>
<script>
function test(x){
    alert(x);
}
</script>
<body>

<div id="main">
</div>

<script>
var backupData = [];
//SAMPLE DATA
backupData.push(['dan','martin']);
backupData.push(['nancy','smith']);
backupData.push(['mary','fisher']);


tbl  = document.createElement('table');
for(var i = 0; i < backupData.length; i++){
    var tr = tbl.insertRow();
    tr.onclick = function(){test(i)};

    var td = tr.insertCell();
    td.appendChild(document.createTextNode(backupData[i][0]));

    var td2 = tr.insertCell();
    td2.appendChild(document.createTextNode(backupData[i][1]));

}
main.appendChild(tbl);
</script>

</body>
</html>
rerat
  • 321
  • 3
  • 14

1 Answers1

3

classic problem of closure

solution 1:

for(var i = 0; i < backupData.length; i++){
    var tr = tbl.insertRow();
    tr.onclick = (function(value){
      //captures local value of i as value parameter
      return function(){
         test(value)
      }
    })(i);

solution 2:

//given backupDate is an array (if a map use Object.keys(backupData)
backupData.forEach(function(i){
    var tr = tbl.insertRow();
    tr.onclick = function(){test(i)};
})
grodzi
  • 5,633
  • 1
  • 15
  • 15