Element inside loop having last loop value for all ids [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I have a while loop that loops 6 times, each time its loops a TD element is create as well as setting an id to it, the problem im having is that the id for everysingle one of the TDs is having the last result of the loop.
var table = document.getElementById("table_calendar");
var tr = document.createElement("tr");
var td;
var days_displayed = 1;
while(i<=6){
td = document.createElement("td");
td.innerHTML = days_displayed;
td.classList.add("tdd");
td.id = year+"-"+month +"-"+days_displayed;
console.log(days_displayed);
td.onclick = function(){
alert(td.id);
};
days_displayed++;
i++;
tr.appendChild(td);
}
table.appendChild(tr);
The alert function is showing this for any TD that I click 2018-02-6
The innerHTML is having different values such as 1 2 3 4 5 6
Am I missing something?

You should access the id of the HTML element using this:
var table = document.getElementById("table_calendar");
var tr = document.createElement("tr");
var td;
var days_displayed = 1;
var year = "2028"
var month = "02"
var i = 0
while(i<=6){
td = document.createElement("td");
td.innerHTML = days_displayed;
td.classList.add("tdd");
td.id = year+"-"+month +"-"+days_displayed;
console.log(days_displayed);
td.onclick = function(){
alert(this.id);
};
days_displayed++;
i++;
tr.appendChild(td);
}
table.appendChild(tr);
<table>
<tr id="table_calendar">
</tr>
</table>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
What happens here is that your td.id will return the last element created, because it has been declared as a var outside the loop. The scope of var is not limited to the block inside {}. If you want the variable to be block scoped you have to use let instead:
var table = document.getElementById("table_calendar");
var tr = document.createElement("tr");
var days_displayed = 1;
var year = "2028"
var month = "02"
for(let i = 0; i <= 6; i++){
let td = document.createElement("td");
td.innerHTML = days_displayed;
td.classList.add("tdd");
td.id = year+"-"+month +"-"+days_displayed;
console.log(days_displayed);
td.onclick = function(){
alert(td.id);
};
days_displayed++;
tr.appendChild(td);
}
table.appendChild(tr);
<table>
<tr id="table_calendar">
</tr>
</table>
What's the difference between using "let" and "var" to declare a variable?
Greetings

Related

How to get innerHTML of td in dynamically populated table in JavaScript

I created a table and populated values from an array, so I have 5x5 table, where each td will be filled with a word. The word come from array memo and all the code below works fine.
var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
table.border = '1'
table.appendChild(tableBody);
//TABLE ROWS
for (i = 0; i < this.memo.length; i++) {
var tr = document.createElement('TR');
for (j = 0; j < this.memo[i].length; j++) {
var td = document.createElement('TD');
td.onclick = function () {
check();
}
td.appendChild(document.createTextNode(this.memo[i][j]));
tr.appendChild(td)
}
tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);
I have one question : I would like to click on the cell and get the word, which belongs to the cell.
For this purpose I tried onclick as I created td element
td.onclick = function () {
check();
}
The function check should print the innerHTML of the cell, which was clicked
function check() {
var a = td.innerHTML;
console.log(a);
}
But it gives me always wrong text - the last one in the array, which was populated.
How could I solve it?..
You always get the last td in the array because the last value that was set to td was of the last cell. You need to add the a parameter, say event, to onclick's callback function, and then your clicked element will be referenced in event.target. Then you would be able to get it's innerHTML.
Here's why it's always giving you the first element: after the for (j = 0; ... loop is finished, the variable td will hold the value of the last element in the list. Then, when check is called, it accesses that same td variable pointing to the last element.
To solve this, you can add an argument to the function to accept a specific element and log that.
td.onclick = function () {
check(td);
};
// later...
function check(element) {
var html = element.innerHTML;
console.log(html);
}
I would pass the innerHTML in the click itself - please see working example below, with some mock data for memo.
var myTableDiv = document.getElementById("results")
var table = document.createElement('TABLE')
var tableBody = document.createElement('TBODY')
var memo = [
['joe', 'tom', 'pete'],
['sara','lily', 'julia'],
['cody','timmy', 'john']
]
table.border = '1'
table.appendChild(tableBody);
//TABLE ROWS
for (i = 0; i < this.memo.length; i++) {
var tr = document.createElement('TR');
for (j = 0; j < this.memo[i].length; j++) {
var td = document.createElement('TD');
td.onclick = function () {
check(this.innerHTML);
}
td.appendChild(document.createTextNode(this.memo[i][j]));
tr.appendChild(td)
}
tableBody.appendChild(tr);
}
myTableDiv.appendChild(table);
function check(a) {
console.log(a);
}
<div id="results">
</div>
you can try..
td.onclick = function () {
check();
}
to
td.onclick = function (evt) {
var html = evt.target.innerHTML;
console.log(html);
check(html); //to do something..
}

How to numbering div?

Can you help me plz. In my code i create elements(div) with table elements in it.
When i put "blue_button" - creates a new div with table in it. The table has 5 td rows. I need to numbering only 1st rows. I mean when i put blue_button twice, the first row in first table in first div - has number 1, the second(i need) must have number 2 (for example).
I "broke my brains". Help plz.
Here is my code:
var unitTableTrTd_1 = [];
var unit = document.createElement('div');
var unitTable = document.createElement('table');
unit.appendChild(unitTable);
var unitTableTr = document.createElement('tr');
unitTable.appendChild(unitTableTr);
var unitTableTrTd_1 = document.createElement('td');
var td_1_p = document.createTextNode("1");
unitTableTrTd_1.appendChild(td_1_p);
unitTableTr.appendChild(unitTableTrTd_1);
var unitTableTrTd_2 = document.createElement('td');
unitTableTr.appendChild(unitTableTrTd_2);
var unitTableTrTd_3 = document.createElement('td');
unitTableTr.appendChild(unitTableTrTd_3);
var unitTableTrTd_4 = document.createElement('td');
unitTableTr.appendChild(unitTableTrTd_4);
var unitTableTrTd_5 = document.createElement('td');
unitTableTr.appendChild(unitTableTrTd_5);
unit.id = "block";
wrapper.appendChild(unit);
Its very simple,
take a global variable table_index ( outside button click's callback )
var table_index = 0;
now on each button click's callback increment the table_index by 1, and use it;
table_index++;
var td_1_p = document.createTextNode( table_index );

Dynamically creating a table

I'm trying to create a table dynamically using JavaScript. So far i'm trying to understand what am i doing wrong. At first i'm making a table element and then i set id for that element. After that i'm looping through rows and as i do that, i create new columns in each new row. The problem which i'm having is that it stops making only 1st row. Can someone point out mistake im making?
var x = document.createElement("TABLE");
x.setAttribute("id", "newTable");
document.body.appendChild(x);
for (i=1;i<5;i++){
var y = document.createElement("TR");
y.setAttribute("id", "newTr");
document.getElementById("newTable").appendChild(y);
for (j=1;i<10;i++){
var z = document.createElement("TD");
var t = document.createTextNode("cell");
z.appendChild(t);
document.getElementById("newTr").appendChild(z);
}
}
var x = document.createElement("TABLE");
x.setAttribute("id", "newTable");
document.body.appendChild(x);
for (i=1;i<5;i++){
var y = document.createElement("TR");
y.setAttribute("id", "newTr"+i);
document.getElementById("newTable").appendChild(y);
for (j=1;j<10;j++){
var z = document.createElement("TD");
var t = document.createTextNode("cell");
z.appendChild(t);
document.getElementById("newTr" +i).appendChild(z);
}
}
i changed your second for-loop from i to j and i made the td-element id unique.
I think you will find that you mixed up jand i
for (j=1;i<10;i++){
var z = document.createElement("TD");
var t = document.createTextNode("cell");
z.appendChild(t);
document.getElementById("newTr").appendChild(z);
}
try
for (i=1;i<10;i++){ //j here changed to i;
var z = document.createElement("TD");
var t = document.createTextNode("cell");
z.appendChild(t);
document.getElementById("newTr").appendChild(z);
}

DOM Add Table Row Where I Want It [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to do insert After() in JavaScript without using a library?
Currently this script adds a row at the bottom of the table. How do I tell it to add it after a particular row? At the top of the table?
<script>
var i = 1;
function changeIt() {
var tr = document.createElement('tr');
var td = tr.appendChild(document.createElement('td'));
td.style.valign = 'middle';
var span = td.appendChild(document.createElement('span'));
span.style.fontWeight = 'bold';
span.appendChild(document.createTextNode('URL ' + i));
td = tr.appendChild(document.createElement('td'));
var input = td.appendChild(document.createElement('input'));
input.name = 'url' + ++i;
input.type = 'text';
input.size = '40'
document.getElementById('myTable').tBodies[0].appendChild(tr);
}
</script>
I've been searching Google to learn, but I keep coming across jQuery, innerhtml, and insertrow answers.
You're looking for node.insertBefore() https://developer.mozilla.org/en-US/docs/DOM/Node.insertBefore
var i = 1;
function changeIt() {
var tr = document.createElement('tr');
var td = tr.appendChild(document.createElement('td'));
td.style.valign = 'middle';
var span = td.appendChild(document.createElement('span'));
span.style.fontWeight = 'bold';
span.appendChild(document.createTextNode('URL ' + i));
td = tr.appendChild(document.createElement('td'));
var input = td.appendChild(document.createElement('input'));
input.name = 'url' + ++i;
input.type = 'text';
input.size = '40'
var node = document.getElementById('myTable').tBodies[0];
node.insertBefore(tr, node.firstChild);
}
To add to a specific position you will need to know the index in the .children. Otherwise some key identifier (class name, attribute, or ID), something you can pass into a getBy or QSA.

JavaScript/DOM - Give a newly created element an ID

How can I apply an element ID to a newly created element through JavaScript DOM?
The code I have written creates a table which is triggered from a button.
I need to apply a unique ID to this table so it can be styled differently to others which appear on my site.
Here is a sample of my code:
var tab = document.createElement("ViewShoppingCart");
document.getElementById("shopping_list").appendChild(tab);
var tbdy = document.createElement("tbody");
tab.id = "new_cart";
tab.appendChild(tbdy);
new_cart = true;
var total = 0;
for (var a = 0; a <= nameArray.length-1; a++) {
var tr = document.createElement("tr");
tbdy.appendChild(tr);
var td = document.createElement("td");
td.appendChild(document.createTextNode("x " + quantityArray[a]));
tr.appendChild(td);
var td2 = document.createElement("td");
td2.appendChild(document.createTextNode(nameArray[a]));
tr.appendChild(td2);
var td3 = document.createElement("td");
td3.appendChild(document.createTextNode(sumArray[a]));
tr.appendChild(td3);
}
Try
var tbdy = document.createElement("tbody");
tbdy.id = "newtbodyid";
tab.id = "new_cart";
tab.appendChild(tbdy);
new_cart = true;
For applying styles consider using class selectors, you may not need IDs at all.
Note that if you want to create valid HTML you can't have duplicated IDs that significantly lessens value for CSS styles, especially for table data.

Categories

Resources