HTML dynamic table row is not getting dynamic id - javascript

I have a dynamic HTML table that makes a new row when there is a new user being registered. Now i am trying to give the row a id with a for loop but they al get the same id which is: tableID99. Here's my code:
for (var i = 0; i < 100; i++) {
row.id = "tableID" + i
}
It looks like the table does not know it is dynamic or something. When i console.log(row.id) it is an ascending list with tableID1 -> tableID1 -> tableID2 etc.
What am i missing here?
Edit:
function showTable() {
// dummy data to start with
let localStorageData = JSON.parse(localStorage.getItem("users"))
// get button and table with query selector
let createTable = document.querySelector("#table")
// table heading
let headers = ["ID", "Gebruikersnaam", "Email", "Wachtwoord", "Gebruikersrol", "Voornaam", "Achternaam", "Geboortedatum", "Adres", "Huisnummer", "Postcode", "Plaatsnaam", "Land", "Suspended"]
// create table elements
let table = document.createElement("table");
let headerRow = document.createElement("tr");
// start loop
headers.forEach(headerText => {
// create table heading and textnode
let header = document.createElement("th");
let textNode = document.createTextNode(headerText);
// append to DOM
header.appendChild(textNode);
headerRow.appendChild(header);
table.appendChild(headerRow)
});
// create loop that makes table
localStorageData.forEach(localStorageData => {
blokkeerButtons()
// create table row
let row = document.createElement("tr");
// create loop that set data in cells
Object.values(localStorageData).forEach(localStorageData => {
// create element and textnode
let cell = document.createElement("td");
let textNode = document.createTextNode(localStorageData as string);
// append to DOM
cell.appendChild(textNode);
row.appendChild(cell);
for (var i = 0; i < 100; i++) {
row.id = "tableID" + i
console.log(row.id)
}
});
// append to DOM
table.appendChild(row);
});
// append to DOM
createTable.appendChild(table);
}

It looks like you have 3 loops in your code to create the table: localStorateData.foreach, Object.values(localStorageData).forEach, and that for loop that counts from 0 to 99.
You are making exactly one new row in the outermost loop. In that innermost for loop, all you're doing is resetting the id of that one new row 100 times.
Consider changing to something like this:
// create loop that makes table
var rowCount = 0;
localStorageData.forEach(localStorageData => {
blokkeerButtons()
// create table row
let row = document.createElement("tr");
// create loop that set data in cells
Object.values(localStorageData).forEach(localStorageData => {
// create element and textnode
let cell = document.createElement("td");
let textNode = document.createTextNode(localStorageData as string);
// append to DOM
cell.appendChild(textNode);
row.appendChild(cell);
});
// append to DOM
row.id = "tableID" + rowCount;
rowCount++;
table.appendChild(row);
});

Related

Having trouble creating a combo-box using javascript

I need help creating a combo-box in my js file for the timesheet application? So there is an add row button in the timesheet which will create a new Row. I would like to have a drop-down + input for the first column in the row which will list the customers. Initially, there is no row in the timesheet application user will need to add a row to submit the timesheet. After clicking the add row it will create a row in which I would like to have a drop-down in the "Project Code" section which lists Internal Timesheet Application our customers. The JS code I used to create the table is as follows:
var arrHead = new Array(); // array for header.
arrHead = ['', 'Project Code', 'Project Description', 'Billable Hours'];
// first create TABLE structure with the headers.
function createTable() {
var empTable = document.createElement('table');
empTable.setAttribute('id', 'empTable'); // table id.
var tr = empTable.insertRow(-1);
for (var h = 0; h < arrHead.length; h++) {
var th = document.createElement('th'); // create table headers
th.innerHTML = arrHead[h];
tr.appendChild(th);
}
var div = document.getElementById('cont');
div.appendChild(empTable); // add the TABLE to the container.
}
//Creating a drop-downlist for Project Code
// now, add a new to the TABLE.
function addRow() {
var empTab = document.getElementById('empTable');
var rowCnt = empTab.rows.length; // table row count.
var tr = empTab.insertRow(rowCnt); // the table row.
tr = empTab.insertRow(rowCnt);
for (var c = 0; c < arrHead.length; c++) {
var td = document.createElement('td'); // table definition.
td = tr.insertCell(c);
if (c == 0) { // the first column.
// add a button in every new row in the first column.
var button = document.createElement('input');
// set input attributes.
button.setAttribute('type', 'button');
button.setAttribute('value', 'Remove');
// add button's 'onclick' event.
button.setAttribute('onclick', 'removeRow(this)');
td.appendChild(button);
}
else {
// 2nd, 3rd and 4th column, will have textbox.
var ele = document.createElement('input'); //I would like create a combo-box for 2nd Column
ele.setAttribute('type', 'text');
ele.setAttribute('value', '');
td.appendChild(ele);
}
}
}
// delete TABLE row function.
function removeRow(oButton) {
var empTab = document.getElementById('empTable');
empTab.deleteRow(oButton.parentNode.parentNode.rowIndex); // button -> td -> tr.
}
// function to extract and submit table data.
function submit() {
var myTab = document.getElementById('empTable');
var arrValues = new Array();
// loop through each row of the table.
for (row = 1; row < myTab.rows.length - 1; row++) {
// loop through each cell in a row.
for (c = 0; c < myTab.rows[row].cells.length; c++) {
var element = myTab.rows.item(row).cells[c];
if (element.childNodes[0].getAttribute('type') == 'text') {
arrValues.push("'" + element.childNodes[0].value + "'");
}
}
}
// The final output.
document.getElementById('output').innerHTML = arrValues;
}
//console.log (arrValues); // you can see the array values in your browsers console window. Thanks :-)
Here is the solution to my Problem:
To make a combo-box for only one column
// now, add a new to the TABLE.
function addRow() {
var empTab = document.getElementById('empTable');
var rowCnt = empTab.rows.length; // table row count.
var tr = empTab.insertRow(rowCnt); // the table row.
tr = empTab.insertRow(rowCnt);
for (var c = 0; c < arrHead.length; c++) {
var td = document.createElement('td'); // table definition.
td = tr.insertCell(c);
if (c == 0) { // the first column.
// add a button in every new row in the first column.
var button = document.createElement('input');
// set input attributes.
button.setAttribute('type', 'button');
button.setAttribute('value', 'Remove');
// add button's 'onclick' event.
button.setAttribute('onclick', 'removeRow(this)');
td.appendChild(button);
}
**else if (c==1) {**\\ Defining the first column with a drop-down
var values = ["","Tiger", "Dog", "Elephant"];
var select = document.createElement("select");
select.name = "pets";
select.id = "pets";
for (const val of values) {
var option = document.createElement("option");
option.value = val;
option.text = val.charAt(0).toUpperCase() + val.slice(1);
select.appendChild(option);
}
td.appendChild(select);
}
else{
// 3rd and 4th column, will have textbox.
var ele = document.createElement('input');
ele.setAttribute('type', 'text');
ele.setAttribute('value', '');
td.appendChild(ele);
}
}
}

Add links to all cells in column of html table

I would like to loop through the cells in the second column of an html table, adding a link to the text in each cell. I have a generic base URL, with a hash that should be defined by an integer in the corresponding cell in the first column of the table.
For example, the text in first cell of the second column should link to:
http://test.example.com/foo.html#1
Where the #1 is defined by the integer in the first cell of the first column (1). Then repeat for each row, where the integer in each cell of the first column should be used for the hash.
Pure js or jquery would work. I have found this snippet of jquery, which seems like a good start for iterating through each cell in the second column:
$('#table1 td:nth-child(2)').each(function(elem) {
//do something with elem
});
Is this jquery method appropriate, and if so, how can I apply the links as described?
As a possible alternative, could I modify the function I use to create the table?:
function createTable(tableData) {
var table = document.getElementById('table1');
var tableBody = document.createElement('tbody');
tableData.forEach(function(rowData) {
var row = document.createElement('tr');
rowData.forEach(function(cellData) {
var cell = document.createElement('td');
cell.appendChild(document.createTextNode(cellData));
row.appendChild(cell);
});
tableBody.appendChild(row);
});
table.appendChild(tableBody);
document.getElementById('wrapper').appendChild(table);
}
createTable(table_input);
Since you are the one creating the table at the first place it is best to modify the code and render it correctly (as oppose to updating it later on client-side).
Based on your comments and clarification here is the updated code, storing the integer value of first column of each row to use it as url on second column:
function createTable(tableData) {
var table = document.getElementById('table1');
var tableBody = document.createElement('tbody');
var theUrl = 'http://test.example.com/foo.html#'; //replace with real URL
tableData.forEach(function(rowData) {
var row = document.createElement('tr');
var i = 1;
var numValue = '';
var content = '';
rowData.forEach(function(cellData) {
var cell = document.createElement('td');
numValue = (i==1) ? cellData : numValue ;
if(i==2){
content = document.createElement('a');
content.setAttribute('href', theUrl + numValue);
content.innerText = cellData ;
}
else{
content = document.createTextNode(cellData);
}
cell.appendChild(content);
row.appendChild(cell);
i++;
});
tableBody.appendChild(row);
});
table.appendChild(tableBody);
document.getElementById('wrapper').appendChild(table);
}
createTable(table_input);
You may change the following code:
rowData.forEach(function(cellData) {
var cell = document.createElement('td');
cell.appendChild(document.createTextNode(cellData));
row.appendChild(cell);
});
to
for (var i=0; i<rowData.length;i++)
{
var cell = document.createElement('td');
if (i==1)
{
var link=document.createElement("a");
link.href="http://test.example.com/foo.html#"+(i+1);
link.text=rowData[i];
cell.appendChild(link);
}
else
cell.textContent=rowData[i];
row.appendChild(cell);
}

JS - Access a <table> from the DOM (error: "TypeError: tablex[0] is undefined")

I want to add <th> headers to a <table> that does not have an "id" but which is in a <div> having a known "id" so I traverse the DOM to find it:
// search <table>
var c = document.getElementById("tablediv").children;
var i; for(i = 0; i < c.length; i++)
{ Output("- " + c[i].nodeName + "<br>"); // show progress
if(c[i].nodeName == "TABLE") break; }
var tablex = c[i]; // that's the right object
var columns = tablex[0].length; // "TypeError: tablex[0] is undefined"
var row = tablex.insertRow(-1);
for(var i = 0; i < columns; i++)
{ var headerCell = document.createElement("TH");
headerCell.innerHTML = tablex[1][i];
row.appendChild(headerCell);
}
And when tablex[0].length; is run it raises "TypeError: tablex[0] is undefined".
I guess var tablex is an incorrect way to assign c[i];.
Can you please let me know how to do it right?
NOTE: the first TD row of the table contains the column titles so either we convert this row to TH or we fetch titles and delete the TD row after a TH row was inserted.
First of all, you don't need to traverse like that. It's easier to query the table directly with querySelector('#tablediv table'). Notice the use of querySelector instead of querySelectorAll, this returns first table inside the node with requested ID.
So the final code would look like this:
var table = document.querySelector('#tablediv table');
// Here you can add check if the table was found (not null) - I'll leave that to you
var firstRow = table.querySelector('tr');
var columns = firstRow.querySelectorAll('td'); // Or th if you have a header cells
console.log(`Number of columns: ${columns.length}`);
var headerRow = document.createElement('tr');
firstRow.parentNode.insertBefore(headerRow, firstRow);
for(var i = 0; i < columns.length; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = columns[i].innerHTML;
headerRow.appendChild(headerCell);
}
firstRow.remove();
Considering the fact that tablex would optimally be a HTMLTableElement, tablex[0] is not defined.

Add table header for dynamic table in javascript

I'm trying to create a table in javascript and put a header on it. I tried to incorporate the answer from this SO question but perhaps I didn't include it in the right place. The body of the table works perfectly, but the header appends as a bunch of text to the top instead of a nicely formatted header. Here is the code:
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
var header = '<tr><th>Country</th><th>City</th></tr>';
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
tbl.append(header)
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
It prints the rows and the columns correctly, but instead of interpreting the <tr><th> as HTML tags it just prints them out as text. I've also noticed that if the table text contains any HTML tags, like <strong> or <b>, they are returned as plain text as well. How can I make them be read as HTML. I have a CSS page as well but there's no reset or anything (intentionally) affecting the use of bold or tables. Here's my result
<tr><th>Country</th><th>City</th></tr>
1 Row 1 text
2 Row <b>2</b> text
Solution1
The way you are appending tbody rows, you can insert the heading as well. So instead of tbl.append(header) and defining the header string, you can use something like below:
results = {
weak_sent: [
"row 1 data",
"row 2 data"
],
weak_sent_num: [1,2]
}
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
// var header = '<tr><th>Country</th><th>City</th></tr>';
var header= document.createElement('thead')
var headingRow = document.createElement('tr')
var headingCell1 = document.createElement('td')
var headingText1 = document.createTextNode('country')
headingCell1.appendChild(headingText1)
headingRow.appendChild(headingCell1)
var headingCell2 = document.createElement('td')
var headingText2 = document.createTextNode('City')
headingCell2.appendChild(headingText2)
headingRow.appendChild(headingCell2)
header.appendChild(headingRow)
tbl.appendChild(header)
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// This is for the quick solution
// tbl.innerHTML = header
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
generate_table()
Solution2
As a quick solution you can use innerHTML property, as shown below.
results = {
weak_sent: [
"row 1 data",
"row 2 data"
],
weak_sent_num: [1,2]
}
function generate_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
//var header = document.createElement("header");
var header = '<tr><th>Country</th><th>City</th></tr>';
//var header = "<th>Header</th>";
var tblBody = document.createElement("tbody");
// creating all cells
for (var i = 0; i < results.weak_sent.length; i++) {
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j == 0) {
var cellText = document.createTextNode(results.weak_sent_num[i]);
} else {
var cellText = document.createTextNode(results.weak_sent[i]);
}
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// This is for the quick solution
tbl.innerHTML = header
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
generate_table()

How to assign variable ids to tables rows and columns

How can I assign ids to the rows, columns if I want to use this method for creating tables. Knowing that the ids are variables, eg. array length.
function addRow(tableID, text) {
// Get a reference to the table
var tableRef = document.getElementById(tableID);
// Insert a row in the table
var newRow = tableRef.insertRow();
// Insert a cell in the row
var newCell = newRow.insertCell();
// Append a text node to the cell
var newText = document.createTextNode(text);
newCell.appendChild(newText);
}
// Call addRow(text) with the ID of a table
addRow('TableA', 'Brand new row');
addRow('TableA', 'Another new row');
Let us say you want to add k rows. Simple, create the rows in a loop of k iteration.
var tableRef = document.getElementById(tableID);
//to add k rows
for (x=0; x<k; x++)
{
// Insert a row in the table
var newRow = tableRef.insertRow(x);
newRow.setAttribute("id","row"+x);
// Insert a cell in the row
var newCell = newRow.insertCell(0);
// Insert another cell in the row
var newCell2 = newRow.insertCell(1);
//insert HTML text in the cells
newCell.innerHTML="text1";
newCell2.innerHTML="text2";
} //end for
}//end function

Categories