I am gathering JSON string data on a button click. Each time I click the button another product gets added to the array. The array is an array of objects:
{SKU: "9372983-382L", retail_price: "11.75", list_price: "3.50", product_name: "Tennis balls"}
How would I take this information and insert it into a table? say I have
<div id='table'>
<table>
</table>
</div>
JavaScript:
var prodArr=[{SKU: "9372983-382L", retail_price: "11.75", list_price: "3.50",
product_name: "Tennis balls"}];
function buildTable(data){
var table = document.getElementById('table');
const arr = data;
for(var obj of arr){
var row = document.createElement('tr');
for(var val of Object.values(obj)){
var col = document.createElement('td');
col.textContent = val;
row.appendChild(col);
}
table.appendChild(row);
}
}
buildTable(prodArr);
I would like to add headers for SKU:, retail_price:, list_price: product_name: and a textbox for quantity on each row as well.
You can loop over the array, use Object.values to loop over the values of the object, and use document.createElement to create new table rows to add to the table.
const table = document.getElementById('table');
const arr = [{SKU: "9372983-382L", retail_price: "11.75", list_price: "3.50", product_name: "Tennis balls"}];
for(const obj of arr){
const row = document.createElement('tr');
for(const val of Object.values(obj)){
const col = document.createElement('td');
col.textContent = val;
row.appendChild(col);
}
table.appendChild(row);
}
table, tr, td, th {
border: 1px solid black;
border-collapse: collapse;
padding: 2px;
}
<table id="table">
</table>
Related
I have a simple table in HTML and I'm trying to edit a particular cell containing a number.
My arrays all have data in them and the table is created OK.
I want to have an edit box for the number in row3 col 2.
I have tried lots of things but nothing seems to work for me.
Needless to say I am a newbie at JS !!
Thanks,
Chris
Update - I have cracked it! more by luck than judgement.
This code does exactly what I want, but I'm finding it difficult to display for you. It works fine on codepenio.
<p id="dt"></p>
<table id="myTable">
<caption>Current values</caption>
<tr>
<th>Item</th>
<th>value</th>
<th>units</th>
</tr>
</table>
<!--
<input type="button" onclick="createRow()" value="Create Row" />
-->
<style>
table {
width: 400px;
}
th {
text-align: center;
}
table,
th,
td {
border: 1px solid #000;
border-collapse: collapse;
}
th,
td {
padding: 5px;
}
</style>
<script>
let numberOfrows = document.getElementById("myTable").rows.length;
let numberoftds = document.getElementById("myTable").rows[0].cells.length;
document.getElementById("dt").innerHTML = Date();
// All names including blanks are placed in array below P01 - P30 incl
pname_english =
"#cabinet model#Serial number#Face velocity#Face velocity alarm setpoint?#Laminar flow velocity#Laminar flow velocity alarm point?#Extract volume#Extract volume alarm point?#Filter pressure#Filter pressure alarm point?#filter saturation value#Hydrocarbon filter monitor#Formaldehyde filter condition monitor#UV tube hours run#Cabinet hours run#service due date#main carbon filter type#main carbon filter date fitted#";
let pnamearray = "pname_english";
pnamearray = pname_english.split("#");
name = "#p01AB200#P021234#P033.4#P041.2#P054.2#P064.8#P072.9#P083.2?#p092332";
let myarray = "name";
myarray = name.split("#");
units = "# # #m/s#m/s#m/s#m/s#Pa#Pa?# ";
let unitsarray = "units";
unitsarray = units.split("#");
console.log("Hello World!");
let col1 = "";
let col2 = "";
let col3 = "";
function createRow() {
//() causes the function to execute anyway!
var row = document.createElement("tr"); // create row node
col1 = document.createElement("td"); // create column node
col2 = document.createElement("td"); // create second column node
col3 = document.createElement("td"); // create second column node
row.appendChild(col1); // append first column to row
row.appendChild(col2); // append second column to row
row.appendChild(col3); // append second column to row
// col1.innerHTML = ""; // put data in first column
// col2.innerHTML = ""; // put data in second column
col3.innerHTML = ""; // put data in second column
var table = document.getElementById("myTable"); // find table to append to
table.appendChild(row); // append row to table
}
var table = document.getElementById("myTable");
var row = document.getElementsByTagName("tr")[0];
let l = 0;
for (i = 0; i < 8; i++) {
// add i rows to myTable
l = myarray[i].length;
col1.innerHTML = pnamearray[i]; // name column
col2.innerHTML = myarray[i].substring(3, l); //value column myarray[i];
col3.innerHTML = unitsarray[i]; //units column
if (i == 3) {
col2.innerHTML =
'<input type="number" id="tentacles" name="tentacles" min="10" max="100" value="20">';
}
createRow(); // create new row
}
</script>
</body>
document.getElementById("Table_ID").rows[YourRowIndex].cells.item(CellIndex)
RowIndex: Start from 0 to n-1( n is number of rows)
CellIndex: Start from 0 to m-1( m is number of cells per each row)
I have a table that is created by javascript when it obtains data from the data base, this is the function
function gotCData(snapshot){
snapshot.forEach(userSnapshot => {
var confirmed = userSnapshot.val().confirmed;
var date = userSnapshot.val().date;
var deaths = userSnapshot.val().deaths;
var recovered = userSnapshot.val().recovered;
//console.log(confirmed, date, deaths, recovered);
var local = k;
var csvDate = date;
var population = recovered;
var totalCases = confirmed;
var totalDeaths = deaths;
//console.log(location);
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var td3 = document.createElement('td');
var td4 = document.createElement('td');
var td5 = document.createElement('td');
var tdLocal = document.createTextNode(local);
var tdPopulation = document.createTextNode(population);
var tdTotalCases = document.createTextNode(totalCases);
var tdTotalDeaths = document.createTextNode(totalDeaths);
var tdDate = document.createTextNode(csvDate);
td1.appendChild(tdLocal)
td2.appendChild(tdPopulation)
td3.appendChild(tdTotalCases)
td4.appendChild(tdTotalDeaths)
td5.appendChild(tdDate)
var tRow1 = document.getElementById("displayCorona").appendChild(td1);
var tRow2 = document.getElementById("displayCorona").appendChild(td2);
var tRow3 = document.getElementById("displayCorona").appendChild(td3);
var tRow4 = document.getElementById("displayCorona").appendChild(td4);
var tRow5 = document.getElementById("displayCorona").appendChild(td5);
//Writes the Table Row then the Divs after
document.getElementById("displayCorona").appendChild(tr, tRow1, tRow2, tRow3, tRow4, tRow5);
});
}
I have a search function :
function search(){
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("displayCorona");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td1")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
The tables are created when I loop through each node in a Firebase database. The search function is from W3Schools but im not sure why it is not searching the table that is created by the above function.
Here's some code for you to look at.
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
window.addEventListener('load', onLoad, false);
function onLoad(evt)
{
var inputStr = "I have a table that is created by javascript when it obtains data from the data base, this is the function";
document.body.appendChild( makeTable(inputStr) );
byId('goBtn').addEventListener('click', onGoBtn, false);
}
function makeTable(input)
{
let tbl = newEl('table');
input = input.replace(',', '');
let words = input.split(' ');
let nWords = words.length;
let nRows = parseInt(nWords/5) + nWords%5;
for (var j=0; j<nRows; j++)
{
let tr = newEl('tr');
for (var col=0; col<5; col++)
{
let td = newEl('td');
td.textContent = words[j*5 + col];
tr.appendChild(td);
}
tbl.appendChild(tr);
}
return tbl;
}
function highlightContainingCells(input, highlightClassname)
{
let cells = document.querySelectorAll('td');
cells.forEach( cellFunc );
function cellFunc(curCell)
{
if (input == curCell.textContent)
curCell.classList.add(highlightClassname);
else
curCell.classList.remove(highlightClassname);
}
}
function onGoBtn(evt)
{
let str = byId('searchStr').value;
highlightContainingCells(str, "found");
}
td
{
color: #333;
background-color: #ddd;
}
td.found
{
color: #ddd;
background-color: #333;
}
<input id='searchStr' value='javascript'/><button id='goBtn'>SEARCH</button></br>
There were so many wrong things.
You had not specified what data type snapshot is. Is it array or something else? I assumed it to be array of JSON objects, where each object denotes a row in your table.
I did not understand the use of .val() method. I removed it completely.
The table being generates was not in correct format. You were appending tr to table. But instead of appending td to tr you were also appending them to table. I have corrected that also.
There was an undefined variable k which was being used to set local.
display:block style on tr was displaying table in a weird way once rows are eliminated. I changed it to display:table-row instead, which is ideal for table-rows
function gotCData(snapshot) {
snapshot.forEach(userSnapshot => {
var confirmed = userSnapshot.val().confirmed;
var date = userSnapshot.val().date;
var deaths = userSnapshot.val().deaths;
var recovered = userSnapshot.val().recovered;
var local = userSnapshot.local; // we will look at this later
// console.log(confirmed, date, deaths, recovered);
// var local = k;
var csvDate = date;
var population = recovered;
var totalCases = confirmed;
var totalDeaths = deaths;
//console.log(location);
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var td3 = document.createElement('td');
var td4 = document.createElement('td');
var td5 = document.createElement('td');
var tdLocal = document.createTextNode(local);
var tdPopulation = document.createTextNode(population);
var tdTotalCases = document.createTextNode(totalCases);
var tdTotalDeaths = document.createTextNode(totalDeaths);
var tdDate = document.createTextNode(csvDate);
td1.appendChild(tdLocal)
td2.appendChild(tdPopulation)
td3.appendChild(tdTotalCases)
td4.appendChild(tdTotalDeaths)
td5.appendChild(tdDate)
tr.appendChild(td1)
tr.appendChild(td2)
tr.appendChild(td3)
tr.appendChild(td4)
tr.appendChild(td5)
// Writes the Table Row then the Divs after
document.getElementById("displayCorona").appendChild(tr);
});
}
function search() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("displayCorona");
tr = table.querySelectorAll("tr:not(.table-head)");
// Loop through all table rows, and hide those who don't match the search query
var found
for (i = 0; i < tr.length; i++) {
tds = tr[i].getElementsByTagName("td")
if (tds) {
found = false
for (j = 0; j < tds.length && found == false; j++) {
td = tds[j];
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "table-row";
found = true
break
}
}
if (found == false) tr[i].style.display = "none";
}
}
}
// This is used for testing only
// window.onload = () => {
// snapshot = firebaseToArray(firebaseJSON)
// gotCData(snapshot)
// }
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
margin-top: 20px;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="myInput">
<button type="submit" onclick="search()">Search</button>
<table id="displayCorona">
<tr class="table-head">
<th>Location</th>
<th>Population</th>
<th>Total cases</th>
<th>Total deaths</th>
<th>Date</th>
</tr>
</table>
</body>
</html>
Some friendly advice:
I see you have extracted data from snapshot and assign them twice to variables, for say you first extract date from snapshot and then assign it to csvDate, while you could directly extract date to csvDate
You were creating text nodes for td, assigning them values and appending them to corresponding td node. You could directly insert data using innerHTML or innerText for example, td1.innerText = local. No need to create textNodes and append them!
It seems like you directly copy-pasted code for search function from w3schools. Please review such codes after using.
Use developer console to find common errors. Debugging your code can solves many common problems, so get familiar with it.
I'm creating a table using JavaScript DOM and I need to insert all the values from the array (thValues) to each of the TH contained in a TR (table row). How I can do it?
let thValues = ["Text 1", "Text 2", "Text 3", "Text 4", "Text 5", "Text 6"];
let pickTableZone = document.getElementById("tableDetails");
let table = document.createElement("table");
pickTableZone.appendChild(table);
table.setAttribute("class", "table table-responsive-sm table-striped");
let tableBody = document.createElement("tbody");
table.appendChild(tableBody); //adding tbody to table
//for the length of thValues create table rows
for (let i = 0; i < thValues.length; i++) {
let tableRow = document.createElement("tr");
tableBody.appendChild(tableRow); //adding TR to TBODY
let tableHead = document.createElement("th");
tableRow.appendChild(tableHead); //adding TH to TR
tableHead.setAttribute("scope", "row"); //adding attributes to TH
let text = document.createTextNode(thValues[0]); //Assign each text from the thValues in each TH from the TR's
tableHead.appendChild(text); //adding text to TH
let tableData = document.createElement("td");
tableRow.appendChild(tableData); //adding TD to TR
let textInTD = document.createTextNode("Time 1");
tableData.appendChild(textInTD); //adding text to TD
}
table, th, td {
border: 1px solid gray;
border-collapse: collapse;
padding: 1rem;
}
<div id="tableDetails">
You need two loops: one to populate the head row with th cells; one to create the body rows with td cells. As it stands, you're creating a new row for each header value instead of putting all of them in a single row. You're also putting your head cells in tbody instead of thead.
Here is how you could create the header row.
const thValues = ["Text 1", "Text 2", "Text 3", "Text 4", "Text 5", "Text 6"];
const pickTableZone = document.getElementById("tableDetails");
const table = document.createElement("table");
pickTableZone.appendChild(table);
table.setAttribute("class", "table table-responsive-sm table-striped");
const tableHead = document.createElement("thead");
table.appendChild(tableHead); //adding thead to table
const headRow = document.createElement("tr");
tableHead.appendChild(headRow); // Row for the head cells.
// Add each header.
for (let i = 0; i < thValues.length; ++i) {
const headCell = document.createElement("th");
headRow.appendChild(headCell); //adding head cell to head row
const text = document.createTextNode(thValues[i]);
headCell.appendChild(text); //adding text to TH
}
const tableBody = document.createElement("tbody");
table.appendChild(tableBody); //adding tbody to table
// for each row of data
// add a tr to tbody
// for each column (e.g. thValues.length)
// add a td to the tr
table, th, td {
border: 1px solid gray;
border-collapse: collapse;
padding: 1rem;
}
<div id="tableDetails"></div>
It's not clear from your post what you want to put in the tbody since you're just repeating "Time 1" over and over. I've therefore left some pseudocode for populating the body.
As an aside, you should use const instead of let unless you plan on reassigning the variable (for a number of reasons).
I realized what I was missing in my code to achieve what I wanted. I forgot to add an i to let text = document.createTextNode(thValues[i]);
let thValues = ["Text 1", "Text 2", "Text 3", "Text 4", "Text 5", "Text 6"];
let pickTableZone = document.getElementById("tableDetails");
let table = document.createElement("table");
pickTableZone.appendChild(table);
table.setAttribute("class", "table table-responsive-sm table-striped");
let tableBody = document.createElement("tbody");
table.appendChild(tableBody); //adding tbody to table
//for the length of thValues create table rows
for (let i = 0; i < thValues.length; i++) {
let tableRow = document.createElement("tr");
tableBody.appendChild(tableRow); //adding TR to TBODY
let tableHead = document.createElement("th");
tableRow.appendChild(tableHead); //adding TH to TR
tableHead.setAttribute("scope", "row"); //adding attributes to TH
let text = document.createTextNode(thValues[i]); //Assign each text from the thValues in each TH from the TR's
tableHead.appendChild(text); //adding text to TH
let tableData = document.createElement("td");
tableRow.appendChild(tableData); //adding TD to TR
let textInTD = document.createTextNode("Time 1");
tableData.appendChild(textInTD); //adding text to TD
}
table, th, td {
border: 1px solid gray;
border-collapse: collapse;
padding: 1rem;
}
<div id="tableDetails">
If I have an object with data structured like this:
{ key1: 1, key2: 2, key3: 3, key4: 4, key5: 5 }
how could I (using pure JS) turn this into a table that looks like this:
sample table format
(the css does not in any way have to look like this. It is simply the formatting I would like)
However, the data that would be put into the table will change, so how could I make that happen automatically?
yes it must be an object.
Thank you so much.
Things that will help:
how to add another row/column to a table
how to assign text value to each cell
how to create a loop that will be able to get the key and the key value of one of the sets in the object
if someone explained the main aspects of what this piece of code means:
function tableCreate() {
//body reference
var body = document.getElementsById("body");
// create elements <table> and a <tbody>
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
// cells creation
for (var j = 0; j <= 2; j++) {
// table row creation
var row = document.createElement("tr");
for (var i = 0; i < 2; i++) {
// create element <td> and text node
//Make text node the contents of <td> element
// put <td> at end of the table row
var cell = document.createElement("td");
var cellText = document.createTextNode("cell is row "+j+", column "+i);
cell.appendChild(cellText);
row.appendChild(cell);
}
//row added to end of table body
tblBody.appendChild(row);
}
// append the <tbody> inside the <table>
tbl.appendChild(tblBody);
// put <table> in the <body>
body.appendChild(tbl);
// tbl border attribute to
tbl.setAttribute("border", "2");
}
<div id="body"></div>
All you need is both name of the key and value. You can use Object.entries()
var data = Object.entries(yourObject);
Loop through this data same as you did above, you can get both key and value.
function tableCreate(dataObj) {
//body reference
var body = document.getElementsByTagName("body")[0];
// create elements <table> and a <tbody>
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
var entries = Object.entries(dataObj);
// cells creation
for (var j = 0; j < entries.length; j++) {
// table row creation
var row = document.createElement("tr");
// Form and set the inner HTML directly
row.innerHTML = `<td>${entries[j][0]}</td>${entries[j][1]}<td></td>`;
//row added to end of table body
tblBody.appendChild(row);
}
// append the <tbody> inside the <table>
tbl.appendChild(tblBody);
// put <table> in the <body>
body.appendChild(tbl);
// tbl border attribute to
tbl.setAttribute("border", "2");
}
The object that you are talking about is a json object
I tell you that how to iterate in that kind of object. Let jsonobj is the object name
for (key in jsonobj){
console.log (jsonobj[key]);}
Now you just have to display data in html tags. I hope rest of the code is not a big challenge for you.
You can try something like this:
Idea
You can create utility function to create row and cell. They are very generic and should be independent of passed data structure or logic to process.
Then you can create a wrapper function that will process the data in necessary format. They can have business logic if you wish to.
This was, you will have a more reusable code and more flexibility
function createTableFromObject(obj, selector) {
var table = document.createElement('table');
for (var k in obj) {
table.appendChild(createRow([k, obj[k]]))
}
addToContainer(selector, table);
}
function createTableFromArray(arr, selector) {
// You can add your logic here.
}
function createRow(values) {
var row = document.createElement('tr');
values.forEach(function(value) {
row.appendChild(createCell(value))
});
return row;
}
function createCell(value) {
var cell = document.createElement('td');
cell.innerHTML = value;
return cell;
}
function addToContainer(selector, element) {
var container = document.querySelector(selector);
container.appendChild(table);
}
var data = { key1: 1, key2: 2, key3: 3, key4: 4, key5: 5 };
createTableFromObject(data, '#content')
/* For demonstration purpose only */
td {
margin: 5px;
background: #ddd;
border: 1px solid black;
width: 50px;
padding: 5px;
}
<div id='content' />
const q3Msg = document.getElementById('tableq3');
var value = [{
id: 1,
result: 65,
situation: 'YES'
}, {
id: 2,
result: 22,
situation: 'NO'
}];
function q3Calc() {
q3Msg.classList.remove('hidden');
var table = document.createElement('tbody'), tr, td, row, cell;
for (row = 0; row < value.length; row++) {
console.log(value);
tr = document.createElement('tr');
for (cell = 0; cell < 3; cell++) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = value;
}
table.appendChild(tr);
}
document.getElementById('tableq3').appendChild(table);
}
I have the above code for automate tds in html. But I have the below image as a result.
How can I show each array index in a separate td?
For example, in the first row, I would like show 1 65 YES, and next row 2 22 NO
Your porblem is in td.innerHTML = value;. Replace it with td.innerHTML = value[row][Object.keys(value[row])[cell]]; to get expected value.
const q3Msg = document.getElementById('tableq3');
var value = [{
id: 1,
result: 65,
situation: 'YES'
}, {
id: 2,
result: 22,
situation: 'NO'
}];
function q3Calc() {
q3Msg.classList.remove('hidden');
var table = document.createElement('tbody'),
tr, td, row, cell;
for (row = 0; row < value.length; row++) {
console.log(value);
tr = document.createElement('tr');
for (cell = 0; cell < 3; cell++) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = value[row][Object.keys(value[row])[cell]];
}
table.appendChild(tr);
}
document.getElementById('tableq3').appendChild(table);
}
q3Calc();
td {
padding: 10px;
border: solid 1px #ddd;
}
<div id="tableq3"></div>
The main problems were that you weren't accessing each element (object in this case) in the array (you never used row after assigning it).
Then you never used the keys within each object (you were just calling value which means each time you were basically grabbing the entire array each time).
const q3Msg = document.getElementById('tableq3');
var value = [{
id: 1,
result: 65,
situation: 'YES'
}, {
id: 2,
result: 22,
situation: 'NO'
}];
function q3Calc() {
q3Msg.classList.remove('hidden');
var table = document.createElement('tbody'), tr, td, row, cell;
for (row = 0; row < value.length; row++) {
console.log(value[row]);
tr = document.createElement('tr');
for (let key in value[row]) {
td = document.createElement('td');
td.innerHTML = value[row][key];
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById('tableq3').appendChild(table);
}
q3Calc();
td {
padding: 5px;
}
<div id='tableq3'>
</div>
Do you want that?
const q3Msg = document.getElementById('tableq3');
var value = [{
id: 1,
result: 65,
situation: 'YES'
}, {
id: 2,
result: 22,
situation: 'NO'
}];
function q3Calc() {
// q3Msg.classList.remove('hidden');
var table = document.createElement('tbody'), tr, td, row, cell;
for (row = 0; row < value.length; row++) {
console.log(value);
tr = document.createElement('tr');
for (cell = 0; cell < 3; cell++) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = '['+value[row].id+','+value[row].result+','+value[row].situation+']';
}
table.appendChild(tr);
}
document.getElementById('tableq3').appendChild(table);
}
q3Calc();
<div id="tableq3"></div>