Storing the index of a for loop in javascript - javascript

I'm developing an android app with phonegap. I'm making an HTML table with some that with a for loop from localStorage. I need, for each row, to store the index i of the for to use it for retrieving an item from localStorage that has the name like the index. I have some code but the variable that i defined for that effect gets overwritten by the loop (of course). Here's the code:
<script language="javascript">
if(len != 0) {
var table = document.getElementById('hor-minimalist-b'); // get the table element
var tableBody = table.childNodes[1]; // get the table body
var tableHead = table.childNodes[0]; // get the table head
var thead = document.createElement('th');
var row2 = document.createElement('tr'); // create a new row
var headText = document.createTextNode('Dados');
thead.scope = "col";
thead.appendChild(headText);
row2.appendChild(thead);
tableHead.appendChild(row2);
for (var i=0; i<len; i++) {
var row = document.createElement('tr'); // create a new row
var cell = document.createElement('td'); // create a new cell
var a = document.createElement('a');
var cellText = document.createTextNode(localStorage.getItem('key' + i));
var xyz = "key" + i;
a.href = "alterar.html";
a.onclick = function() { doLocalStorage(xyz) };
a.appendChild(cellText);
cell.appendChild(a); // append input to the new cell
row.appendChild(cell); // append the new cell to the new row
tableBody.appendChild(row); // append the row to table body
}}
</script>
</table>
Maybe i'm not explaining myself too well. If you need any more info please ask. Thanks in advance. Eva

try to put the key name in to a closure:
function wrapper(i) {
return function() {
doLocalStorage("key" + i)
}}
a.onclick = wrapper(i);

Not sure if I got your question right, but if you want to bind usage of a variable asynchronously when doing for loop then you should wrap it in a closure:
for(i = 1, c = arr.length; i < c; i++){
(function(i){
// i wont change inside this closure so bound events will retain i
$('#id'+i).click(function(){
alert(i); // Will alert the corresponding i
})
})(i);
}

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..
}

Create a bookmarklet that can retrieve all max length of text box and then print the id and max length in a table

I want to create a bookmarklet by using javascript, which can retrieve max length of all text box in the page, and then print a table below the page with all id and max length indicated.
Here is my code, however it did not print anything.
javascript: (function() {
var body =document.getElementsByTagName('body')[0];
var tbl = document.createElement('table');
var tbdy = document.createElement('tbody');
var D = document,
i, f, j, e;
for (i = 0; f = D.forms[i]; ++i)
for (j = 0; e = f[j]; ++j)
if (e.type == "text") S(e);
function S(e) {
var l= document.getElementById(e.id);
var x = document.getElementById(e.maxlength);
var tr=document.createElement('tr');
var td1=document.createElement('td');
var td2=document.createElement('td');
td1.appendChild(document.createTextNode(l));
td2.appendChild(document.createTextNode(x));
tr.appendChild(td1);
tr.appendChild(td2);
tbdy.appendChild(tr);
}
tbl.appendChild(tbdy);
body.appendChild(tbl);
})
This can actually be done much simpler than you have it.
Working jsfiddle: https://jsfiddle.net/cecu3daf/
You want to grab all of the inputs and run a loop over them. From this you can dynamically create a table and append it to the end of the document.body
var inputs = document.getElementsByTagName("input"); //get all inputs
var appTable = document.createElement("table"); //create a table
var header = appTable.createTHead(); //create the thead for appending rows
for (var i=0; i<inputs.length; i++) { //run a loop over the input elements
var row = header.insertRow(0); //insert a row to the table
var cell = row.insertCell(0); //insert a cell into the row
cell.innerHTML = inputs[i].maxLength; //input data into the cell
var cell = row.insertCell(0);
cell.innerHTML = inputs[i].id;
}
document.body.appendChild(appTable); //append the table to the document
To make it a bookmark, simply place the javascript: before hand. There is no need to encase it in a function. You can if you'd like to.

Cannot read property of 'appendchild' of null in a For-Loop

I have a small database that I have retrieved the data from and stored in a HTML table.
This table contains 3 columns and 3 rows.
What I want to do is via javascript create a div for each row, then within this create a div for each cell in that row of the table (to allow me to style it in CSS).
I have created a number of For loops to go through and attempt this, my problem is the second for loop I have created, it goes through once and I receive an error of "Cannot read property 'appendChild' of null". I am not sure why it is doing this. Any help would be appreciated.
var getTable = document.getElementById('projectsTable');
var rowLength = getTable.rows.length;
for (i =0; i< rowLength; i++) {
var divName = 'projects' + i;
block = document.createElement('div');
block.id = divName;
document.getElementById('javascript').appendChild(block);
var getCells = getTable.rows.item(i).cells;
var cellLength = getCells.length;
for (var j = 0; j < cellLength; j++) {
var divName2 = 'projects' + j;
var projectInfo = 'info' + j;
info = document.createElement('div');
info.id = projectInfo;
document.getElementById(divName2).appendChild(info);
var cellVal = getCells.item(j).innerHTML;
var getDiv = document.getElementById(projectInfo);
getDiv.innerHTML = cellVal;
}
}
The first for loop creates the div for the whole row and attaches it to a div in the page that already exists, then I get the error on the 2nd for loop.
You are using many unnecessary variables and definitions. For example divName2 should be same as divName and thus redundant.
I hope this example helps you out.
<!DOCTYPE html>
<html>
<head>
<script>
function loadTable(){
var tT = document.getElementById('projectsTable'); //Source table
var tJ = document.getElementById('javascript'); //New clone container
if (tT && tJ){
for(var i=0, j=tT.rows.length;i<j;i++){
var tP = document.createElement('div'); //Our project div(:=tr)
tP.id = 'projects' + i.toString();
for(k=0, l=tT.rows.item(i).cells.length;k<l;k++){
var tI = document.createElement('div'); //Our info div(:=td)
tI.id = 'info' + k.toString();
tI.innerHTML = (i+1)*k;
tP.appendChild(tI); //We still have the correct project from above, so we just use it.
};
tJ.appendChild(tP); //Adding project to the dom
};
};
};
</script>
</head>
<body onload = 'loadTable();'>
<table id = 'projectsTable'>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</table>
<div id = 'javascript'></div>
</body>
</html>

JavaScript : Delete dynamically created table

I am new to web development and struggling with deleting a dynamically created table.
Below is the JavaScript function to create the table when user clicks a button.
function DrawTable(data){
var oTHead = myTable.createTHead();
var oTFoot = myTable.createTFoot();
var oCaption = myTable.createCaption();
var oRow, oCell;
var i, j;
var heading = new Array();
heading[0] = "AAA";
heading[1] = "BBB";
heading[2] = "CCC";
heading[3] = "DDD";
var tableData = data.split(':');
// Insert a row into the header.
oRow = oTHead.insertRow(-1);
oTHead.setAttribute("bgColor","lightskyblue");
// Insert cells into the header row.
for (i=0; i < heading.length; i++)
{
oCell = oRow.insertCell(-1);
oCell.align = "center";
oCell.style.fontWeight = "bold";
oCell.innerHTML = heading[i];
}
// Insert rows and cells into bodies.
for (i=0; i < tableData.length; i++)
{
var oBody = oTBody0;
oRow = oBody.insertRow(-1);
var splitData = tableData[i].split(',');
for (j=0; j < splitData.length; j++)
{
oCell = oRow.insertCell(-1);
oCell.innerHTML = splitData[j];
}
}
}
The above code works perfectly and draws the table when user clicks on the button.
If user clicks on the button again it will draw the table again.
i.e., it will draw another header and all the rows all over again.
At this point I want to delete the existing header and rows and draw it all new.
I tried many things to delete the existing table, but nothing works.
Is there a way I can make sure that the table is not duplicated again?
UPDATE
The HTML part is:
<table id="myTable">
<tbody ID="oTBody0"></tbody>
</table>
ANOTHER UPDATE
I tried below and it worked.
oTHead.innerHTML = "";
oTBody0.innerHTML = "";
jQuery offers a .empty() function that you can use
$("#myTable").empty();
Or with javascript you can just set the innerHTML to empty
document.getElementById("myTable").innerHTML = "";
Just execute this function before you start trying to add new content to the table.
//$("#myTable").empty();
document.getElementById("myTable").innerHTML = "";
// Insert a row into the header.
oRow = oTHead.insertRow(-1);
oTHead.setAttribute("bgColor","lightskyblue");
// Insert cells into the header row.
for (i=0; i < heading.length; i++) {
oCell = oRow.insertCell(-1);
oCell.align = "center";
oCell.style.fontWeight = "bold";
oCell.innerHTML = heading[i];
}
Since you're using jQuery, just do this: $('#containerIdThatYourTableSitsIn').html('');
That will clear the html of whatever element your table sits in. Then just reload it.
Edit
As the comments have mentioned, .empty() is another option.

how to set onclick attribute in a loop

I am building a table with text in the first column and buttons that do stuff in the second column. Here is the complete .js file:
var table = document.createElement("table");
var tableBody = document.createElement("tbody");
for(i = 0; i < array.length; i++) {
var row = table.insertRow(i);
var cell = row.insertCell(0);
cell.innerHTML = text[i];
var cell = row.insertCell(1);
var cellElement = document.createElement("input");
cellElement.setAttribute("id", ID[i]);
cellElement.setAttribute("type", "button");
cellElement.setAttribute("value", "button");
/////cellElement.onclick =
/////function(){ doThisThing(i,ID[i]); } );
cell.appendChild(cellElement);
row.appendChild(cell);
}
table.appendChild(tableBody);
document.body.appendChild(table);
Everything works except for the cellEllement.onclick = function(){}; The onlick() function does not set. I have tried variations on this:
cellElement.setAttribute("onclick",doThisThing(i,ID[i]));
How to I set the button onclick attribute when looping through to create a table?
You're using a reference to the i variable inside your function which will continue to change with the loop, and won't hold the value of i that it has when you go through that iteration of the loop. You need to hold on to the current value of i, probably by wrapping your callback in another function:
cellElement.onclick = (function(currI) {
return function() { doThisThing(currI, ID[currI]); };
})(i);
You could also use bind to make things simpler:
cellElement.onclick = doThisThing.bind(null, i, ID[i]);

Categories

Resources