Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a click function to cells in a dynamically created table - JavaScript

var tableData = document.getElementsByTagName("td");

for(var i = 0; i < tableData.length; i++){
    var x = tableData[i];
    x.addEventListener("click", fun1(x.textContent));
}
function fun1(y){
    document.getElementById("testB").textContent = y;
}

I am trying to add a click function to every cell in a dynamically created table (i have no way of knowing how many cells are in the table or what their id would be but i only need the text contained in the cell)

I want to update a button with the content of the cell and as of right now it does not update on click and instead updates the button to the last value of the table.

I am fairly new to JavaScript and would appreciate any help you could offer.


here is the solution i used thanks to the answer provided below


var tables = document.getElementsByTagName("table");
for(var i = 0; i < tables.length; i++){
    tables[i].addEventListener("click",
    function(e) {
        if(e.target && e.target.nodeName == "TD") {
            fun1(e.target.textContent);
        }
     }
);
}
function fun1(y){
    document.getElementById("testB").textContent = y;
}

i went with this solution because the script generating the tables is not mine and as such i do not know what the id of the table i want is and do not know how many tables it actually creates.

like image 421
Blake Avatar asked Dec 15 '25 00:12

Blake


2 Answers

You almost certainly do not want to add an event handler individually to each table cell if all (or even many) of them should do the same thing when clicked.

The DOM event model was designed to support delegation, which is a much better solution in cases like this. In brief: individual cells do not respond to clicks, but some ancestor element that is considered a permanent fixture (say, the <table> they are in) detects the clicks on cells and responds to them appropriately.

Here's how to set up delegation:

document.getElementById("#mytable").addEventListener("click",
    function(e) {
        if(e.target && e.target.nodeName == "TD") {
            fun1(e.target.textContent);
        }
     }
);

Of course you can choose any ancestor element you want, even <body> if that's what is required. Also note that this way of doing things means your code behaves as expected even while cells are added to or removed from the table -- you just do this once on page initialization.

like image 86
Jon Avatar answered Dec 16 '25 14:12

Jon


x.addEventListener("click", fun1(x.textContent));

This line is your issue -- addEventListener looks for a function reference, you're just calling the function (which does not return a function). Wrap it in an anonymous function, or bind the value to the reference.

x.addEventListener("click", function() { 
    fun1(x.textContent)
}, false); //also a good idea to add the event bubbling boolean param

Alternatively, ES6 arrow syntax:

x.addEventListener("click", () => fun1(x.textContent), false);
like image 22
Sterling Archer Avatar answered Dec 16 '25 12:12

Sterling Archer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!