0

I have a table in my HTML called id='myTable'. I am then filling in the rows on-the-fly in the JavaScript (because it will constantly be changing throughout the use of the program.)

Elsewhere in the code is the function:

function OnClickRowMyTable(row){
    alert("You clicked row " + row.toString());
}

Then I am constructing the table:

table = document.getElementById("myTable");
for (i = 0; i < 10; i++) {
    newRow = document.createElement('tr');
    newRow.setAttribute('style', "background-color: #FFFFBB");
    newRow.title = "";
    newRow.onclick = (function () { var iUse = i; return OnClickRowMyTable(iUse); })();
    table.appendChild(newRow);

    for (j = 0; j < 5; j++) {
        newCol = document.createElement('td');
        newCol.innerHTML = "-";
        newRow.appendChild(newCol);
    }
}

If I leave the (); on the end of the onclick line, it actually calls the function OnClickRowMyTable several times as the table is constructed.

If I end that line without the (), then the function is not called during construction, but when I do click the row it always says I have clicked row 10, irrespective of the row I have clicked.

How do I stop the function being called during construction, and then say I have clicked the correct row, when i click it, rather than say I have clicked row 10 all the time?

0

2 Answers 2

1

You should wrap the contents of the loop in an Immediately Invoked Function Expression (IIFE) and pass i to it. This will keep the value of i while your table rows are built.

	var table = document.getElementById("myTable");
	for (var i = 1; i <= 10; i++) {
	  (function(i) {
	    var newRow = document.createElement('tr');
	    newRow.setAttribute('style', "background-color: #FFFFBB");
	    newRow.title = "";
	    newRow.onclick = function() {
	      return OnClickRowMyTable(i);
	    };
	    table.appendChild(newRow);

	    for (var j = 0; j < 5; j++) {
	      var newCol = document.createElement('td');
	      newCol.innerHTML = "-";
	      newRow.appendChild(newCol);
	    }
	  })(i);
	}

	function OnClickRowMyTable(row) {
	  alert("You clicked row " + row.toString());
	}
<table id="myTable"></table>

Sign up to request clarification or add additional context in comments.

Comments

0

You should use delegation if you want add elements on the fly.


Check this out: http://api.jquery.com/on/

jQuery JS SOLUTION:

$( "#myTable" ).on( "click", "tr", function() {
   var row = $(this);
    alert("You clicked row " + row.toString());
});

VANILLA JS SOLUTION:

document.addEventListener('click', function(event) {
    if (event.target.id == 'my-id') {
      // put your code here
    }
});

non id version:

document.addEventListener('click', function(event) {
   var t = event.target;
   while (t && t !== this) {
      if (t.matches('tr')) {
          // your code goes here
      }
      t = t.parentNode;
   }
});

8 Comments

I don't see a jQuery tag on this question
The bottom thing looks good, but I do not want to associate ids with the table rows. I want to do something with the 'i' in the loop in my code.
You're probably going to run into a lot of conflicts attempting to have your function inside of your loop like that. Also, it is best practice to pull your action functions into delegation style functions so that you can add new rows to your table without having to worry about adding the onclick function during creation. This also wont force you to have to keep track of your index (or 'i') while you are inserting new rows. You could instead get the row inside of the delegated callback function and use whatever properties from that row you want in the callback function.
if you want a quick solution, try something like this: newRow.onclick = OnClickRowMyTable(i);
@Rewind - I have added a new version that doesn't require you to have an id on each table row
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.