Search code examples
javascripthtmldomhtml-tableonclick

JavaScript Add onclick functions with row number as parameter to dynamically generated rows


The Problem

Hi, I am making a table in which I have two buttons, View and Update for each row. I am generating the rows in one for loop. Since I am using innerHTML, Instead of adding the onclick listeners there, I make another for loop after the first one and add the event listeners there. The event listeners are added to all rows. However, the parameter( Row number) passed in functions for all rows is the number for the last row. Not sure why this is happening, any clues or advice will be helpful. I will leave the relevant code and debugging results below.

The Code

Adding New Rows

table.innerHTML="";
var count=1;
querySnapshot.forEach((doc) => {
  var innerhtml='<tr id="row">.....</tr>';

  //Append the new row
  table.innerHtML=table.innerHTML+innerhtml;

  //Assign new ID to row
  document.getElementById("row").id=count.toString()+"row";
  
  //Increment Count for next row/iteration
  count=count+i;


});

Adding event Listeners for Each Rows

for(var i=1;i<count;i++){
  console.log("Adding functions for row : "+i);

  //Get/Generate ID of rows (ID was assigned with same logic) 

  var cchkid=i.toString()+"chk";
  var uupdateid=i.toString()+"update";
  console.log("Adding functions for row : "+cchkid + " "+uupdateid);

  //Add Listeners for Each button in row i

  document.getElementById(cchkid).addEventListener("click", function(){
    alert("adding check function for id : "+i);
      check(i-1);
  });
  document.getElementById(uupdateid).addEventListener("click", function(){
    alert("adding update function for id : "+i);
      update(i-1);
  });
}

Debugging by using Console Log & Inspect

Count : 3

Adding functions for row : 1 Adding functions for row : 1chk 1update Adding functions for row : 2 Adding functions for row : 2chk 2update

Inspect Using inspect element, I can ensure that all rows have separate id's Inspect Element Screenshot

So far everything looks good, However, when console logged inside the said functions, all rows give the same value for the passed parameter.

Console Log after clicking on two different rows 2 Display data for user ID: 1

This should be :

  1. Display data for user ID: 0 for first row
  2. Display data for user ID: 1 for second row and so on

I cannot figure out what's wrong here, kindly help this newbie out. Thanks!


Solution

  • The answer was simple but took me a little while to figure out. When assigning eventlisteners in a loop, I was using var for the iterator. That is, for(var i=0;i<length;i++). However Inside the listener, the var i doesnot exist even if the listener is added inside the loop because of the scope of var in JS.

    for(var i=0.......){
    button.addeventlistener("click",function(){ myFunc(i); })); 
    }
    

    Changing the var here to let does the trick here. That's it.