Need a clarification on creating dynamic html table using js - javascript

I want to create a dynamic table using html and js. I put the below code and its not working. I can do that in many number of ways. But i want know why this code is not working.
This is my code
let data = [{
id: 1,
name: 'ssss'
},
{
id: 2,
name: 'bbbb'
}
]
document.getElementById("test").innerHTML = `<table><tr><th>S.no</th><th>title</th></tr>`;
data.forEach(item => {
document.getElementById("test").innerHTML += "<tr><td>" + item.id + "</td><td>" + item.name + "</td></tr>";
console.log(item);
});
console.log("ssss");
document.getElementById("test").innerHTML += "</table>";
<p id="test">
</p>
I got the output as below
S.no title
1ssss2bbbb
My expected output is
S.no title
1 ssss
2 bbbb

Put the </table> into the HTML string from the beginning.
test is a <p> element, not a table element. Select the table element instead, which is a direct descendant of the <p>.
If you're confusing yourself, it'll be clearer if you extract the elements into descriptive variable names first, like this:
let data = [{
id: 1,
name: 'ssss'
},
{
id: 2,
name: 'bbbb'
}
]
const p = document.getElementById("test");
p.innerHTML = `<table><tr><th>S.no</th><th>title</th></tr></table>`;
const table = p.children[0];
data.forEach(item => {
table.innerHTML += "<tr><td>" + item.id + "</td><td>" + item.name + "</td></tr>";
});
<p id="test">
</p>

Try to set table after all work done like this:
let data = [{
id: 1,
name: 'ssss'
},
{
id: 2,
name: 'bbbb'
}
]
var x = `<table><tr><th>S.no</th><th>title</th></tr>`;
data.forEach(item => {
x += "<tr><td>" + item.id + "</td><td>" + item.name + "</td></tr>";
});
x += "</table>";
document.getElementById("test").innerHTML = x
console.log(x)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p id="test">
</p>
</body>
</html>

Try to set id for <tbody> part of the table and set the innerHTML with js like below:
let data = [{
id: 1,
name: 'ssss'
},
{
id: 2,
name: 'bbbb'
}
]
document.getElementById("test").innerHTML = `<table><tr><th>S.no</th><th>title</th></tr><tbody id="tableBody"></tbody></table>`;
data.forEach(item => {
document.getElementById("tableBody").innerHTML += "<tr><td>" + item.id + "</td><td>" + item.name + "</td></tr>";
console.log(item);
});
console.log("ssss");
document.getElementById("test").innerHTML += "</table>";
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p id="test" />
</body>
</html>

I have modified your approach a bit:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p id="test">
</table>
</p>
<script>
let data = [{
id: 1,
name: 'ssss'
},
{
id: 2,
name: 'bbbb'
}
]
var table = document.createElement('table');
var thead = document.createElement('thead');
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
var td = document.createElement('td');
var columns = ['S.No','Title'];
var tcol = [];
//creating the header while assuming all the headers are present in 1st row
Object.keys(data[0]).forEach(col=>{
tcol.push(col);
});
for(var i=0;i<columns.length;i++)
{
var th = document.createElement('th');
th.innerHTML = columns[i];
tr.appendChild(th);
}
thead.appendChild(tr);
//appending the created headers to the table object
table.appendChild(thead);
//creating the body
data.forEach(item => {
tr = document.createElement('tr');
for (var i = 0; i < tcol.length; i++) {
var td = document.createElement('td');
td.innerHTML = item[tcol[i]];
tr.appendChild(td);
}
//appending the created row to the table body
tbody.appendChild(tr);
});
table.appendChild(tbody);
//finally putting the table's html to your desired div
document.getElementById("test").innerHTML = table.outerHTML;
</script>
</body>
</html>
I have made an assumption that your 1st row will mostly have a columns in it if not try to pass the columns as a seperate entity.

Related

Multidimensional Array to bootstrap tables

I had a multidimensional array that consists of dynamic elements per subarray. What I was trying to do was construct a bootstrap table by reading the array. To explain the table format better: If my multidimensional array is mdArray = [[name1, name2, name3, name4], [name5, name6, name7]]
I wanted to create a table of 4 columns with mdArray[0], mdArray[1], mdArray[2], mdArray[3] then create an new row when next sub-array is detected with columns mdArray[4], mdArray[5], mdArray[6]. What I have tried is below. How can I achieve this? Any help is appreciated. Thanks in advance?
mdArray = [
['name1', 'name2', 'name3', 'name4'],
['name5', 'name6', 'name7']
]
$('.table').ready(
function() {
console.log('table loaded');
var theTable = "";
for (var j = 0; j < mdArray.length; j++) {
theTable += '<tr class="text-center">';
for (var k = 0; k < 2; k++) {
theTable += '<td> class="text-center"' + mdArray[k][j] + '</td>';
}
theTable += '</tr>';
}
$('.table').append(theTable);
//expected name1 name2 name3 name4
//next row
//name5 name6 name7
});
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
<body>
<table class="table table">
<tbody>
</tbody>
</table>
</body>
Because someone suggested a visual representation:
Is this what you looking for
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
</head>
<body>
<!-- <button onclick="eventEmitArray()">Insert the array</button> -->
<table class="table">
<tbody></tbody>
</table>
</body>
<script>
let mdArray = [
["name1", "name2", "name3", "name4"],
["name5", "name6", "name7"],
];
$(".table").ready(function() {
console.log("table loaded");
var theTable = "";
for (var j = 0; j < mdArray.length; j++) {
theTable += '<tr class="text-center">';
for (var k = 0; k < mdArray[j].length; k++) {
theTable += '<td class="text-center">' + mdArray[j][k] + "</td>";
}
theTable += "</tr>";
}
$(".table").append(theTable);
});
</script>
</html>
You can use forEach loop and you don't need to worry about number of columns and handling array indexes
$('.table').ready(function() {
var theTable = "";
mdArray.forEach((names) => {
theTable += '<tr class="text-center">'
names.forEach((name) => {
theTable += `<td class="text-center">${name}</td>`;
})
theTable += '</tr>'
}
);
$('.table').append(theTable);
});

Make an html table using a JSON object

I know there are a lot of similar questions out there. This code is a Frankenstein of a lot of other stack overflow questions. But I am so close I just don't understand the code I've been trying to use an examples very well.
Here is my html page:
<!DOCTYPE html>
<html>
<script src="Scripts.js"></script>
<script>
</script>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"> </script>
</head>
<body>
<p id="demo"></p>
<script>
obj.Blades.forEach(element => {
var name = element.Name + " " + element.Damage;
document.write(name + "<br >");
});
</script>
<input type="button" value="Generate Table" onclick="makeTable()" />
<hr />
<div id="dvTable"></div>
</body>
</html>
And here is the Java Script page:
var jsonStuff = '{ "Blades" : [' +
'{ "Name":"Longsword" , "Damage":"l2d" },' +
'{ "Name":"Dagger" , "Damage":"l3d" },' +
'{ "Name":"Mace" , "Damage":"l4d" },' +
'{ "Name":"Spear" , "Damage":"l5d" } ]}';
var obj = JSON.parse(jsonStuff);
function makeTable(){
//Create a HTML Table element.
var table = document.createElement("TABLE");
table.border = "1"
//Get the count of columns.
var columnCount = Object.keys(obj.Blades).length;
//Add the header row.
var row = table.insertRow(-1);
for (var i = 0; i < columnCount; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = obj.Blades[i].Name;
row.appendChild(headerCell);
}
//Add the data rows.
for (var i = 1; i < obj.Blades.length; i++) {
row = table.insertRow(-1);
for (var j = 0; j < columnCount; j++) {
console.log(obj.Blades[j].Damage);
var cell = row.insertCell(-1);
cell.innerHTML = obj.Blades[i][j];
}
}
var dvTable = document.getElementById("dvTable");
dvTable.innerHTML = "";
dvTable.appendChild(table);
}
This is what it looks like right now:
So I know the problem has to be somewhere in the section of JavaScript commented "add the Data rows". I'm just now sure how to go about it.
I believe your problem is with the line:
cell.innerHTML = obj.Blades[i][j];
You are referring to Blades as if it were a 2-dimensional array, when in fact it is an array of objects. You're going to need to have something like this to avoid the undefined:
cell.innerHTML = obj.Blades[i].Name;
cell.innerHTML = obj.Blades[i].Damage;

Display sum of specific column in Javascript

I wish to display sum of amount for particular region.
Below is my code to display the data, however I am sure how to add up the amount.
I am able to read csv file an display in html table.
I am new to Javascript. Any help to proceed would be much appreciated
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function loadFile(o)
{
var fr = new FileReader();
fr.onload = function(e)
{
showDataFile(e, o);
};
fr.readAsText(o.files[0]);
}
function showDataFile(e, o)
{
var getCSVData = e.target.result;
var rows = getCSVData.split("\n");
var html = '<table border="1">';
rows.forEach((data, index) =>
{
html += "<tr>";
var value = data.split(",");
var region = value[1];
var amount =value[3];
if(region=="SA")
{
html += "<td>" + region + "</td>";
html += "<td>" + amount + "</td>"
}
html += "</tr>";
});
html += '</table>';
document.getElementById("data").innerHTML = html;
document.getElementById("data").style.color="blue";
}
</script>
<title> Read CSV file using JavaScript </title>
</head>
<body>
Select file to read <input type="file" onchange="loadFile(this)">
<pre id="data"></pre>
</body>
</html>
You need to create a variable that you use as an accumulator to save the result of the sum, for example:
var sum = 0;
for (i = 1; i <= 10; i++) {
sum += 10;
}
console.log(sum)
Following your idea, you need to create a variable initialized at 0 before forEach and then inside the loop, accumulate its result
NOTE:
1. When you read your .csv file, it is received as a String, so the value of the variable amount is also a String, so before making the sum it should be transformed to a Number type to avoid concatenate
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)
Solution:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
function loadFile(o)
{
var fr = new FileReader();
fr.onload = function(e)
{
showDataFile(e, o);
};
fr.readAsText(o.files[0]);
}
function showDataFile(e, o)
{
var getCSVData = e.target.result;
var rows = getCSVData.split("\n");
var html = '<table border="1">';
var sum = 0;
rows.forEach((data, index) =>
{
html += "<tr>";
var value = data.split(",");
var region = value[1];
var amount = value[3];
if(region=="SA")
{
if (Number(amount)) {
sum += Number(amount)
}
html += "<td>" + region + "</td>";
html += "<td>" + amount + "</td>"
}
html += "</tr>";
});
html += '</table>';
html += '<span>' + sum + '</span>';
document.getElementById("data").innerHTML = html;
document.getElementById("data").style.color="blue";
}
</script>
<title> Read CSV file using JavaScript </title>
</head>
<body>
Select file to read <input type="file" onchange="loadFile(this)">
<pre id="data"></pre>
</body>
</html>

Scope model update

Below demo app is showing three different progressbars.
Now user needs to select which progressbar he/she wants to change value
and then on button click which is provided at same page.
var app = angular.module('myApp',[]);
app.component('listComponent', {
template:'<div ng-repeat="progress in $ctrl.obj.bars track by $index">' +
'<progress value="{{progress}}" max="{{$ctrl.obj.limit}}">{{progress}}</progress><br>'+
'</div>'+
'<br>' +
'<div>' +
'Selected Progressbar : {{$ctrl.selectedProgressbar}}' +
'<span>' +
'<select name="selectedProgressbar" ng-model="$ctrl.selectedProgressbar">' +
'<option ng-repeat="progress in $ctrl.obj.bars track by $index" value="{{$index}}">{{progress}}</option>' +
'</select>' +
'</span>' +
'<span ng-repeat="btn in $ctrl.obj.buttons">' +
'<button class="btn" ng-click="$ctrl.changeProgress(btn, $ctrl.selectedProgressbar)">{{btn}}</button>' +
'</span>' +
'</div>',
controller: function () {
this.obj = {
"buttons": [
10,
38,
-13,
-18
],
"bars": [
62,
45,
62
],
"limit": 230
};
function changeProgressbar(val){
var val = parseInt(val);
var barValue = this.obj.bars[this.selectedProgressbar];
var selectedBar = this.selectedProgressbar;
var bars = this.obj.bars;
// this.obj.bars[0] = parseInt(this.obj.bars[0]) + parseInt(val);
// if we remove comment from above code and comment below one then progresbar value changes at same time
// but with below code its not changing at same time its changing when we click on any button or change progreebar selection
if(val > 0){
var total = parseInt(barValue) + val;
var update = setInterval(function() {
if (parseInt(barValue) > total) {
clearInterval(update);
}
barValue = parseInt(barValue) + 1;
bars[selectedBar] = barValue;
}, 15);
}
}
this.changeProgress = changeProgressbar;
}
});
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="This is just demo application by using Angular 1.6">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Progressbar in Angular 1.6</title>
<style type="text/css" media="screen">
progress:after {
display: block;
content: attr(value);
text-align:center;
}
</style>
</head>
<body ng-app="myApp">
<list-component></list-component>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script>
</script>
</body>
</html>
jsBin is here,
now after selecting any progressbar then click on any first two buttons then no change is found on progreebar
but as soon as you click again or select some other progressbar then value is changing.
After going through your code, I found some issues there.
You should change the changeProgressbar function and remove the interval function.
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[add your bin description]">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Progressbar in Angular 1.6</title>
<style type="text/css" media="screen">
progress:after {
display: block;
content: attr(value);
text-align:center;
}
</style>
</head>
<body ng-app="myApp">
<list-component></list-component>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script>
var app = angular.module('myApp',[]);
app.component('listComponent', {
// isolated scope binding
template:'{{$ctrl.obj.bars}}<div ng-repeat="progress in $ctrl.obj.bars track by $index">' +
'<progress value="{{progress}}" max="{{$ctrl.obj.limit}}">{{progress}}</progress><br>'+
'</div>'+
'<br>' +
'<div>' +
'Selected Progressbar : {{$ctrl.selectedProgressbar}}' +
'<span>' +
'<select name="selectedProgressbar" ng-model="$ctrl.selectedProgressbar">' +
'<option ng-repeat="progress in $ctrl.obj.bars track by $index" value="{{$index}}">{{progress}}</option>' +
'</select>' +
'</span>' +
'<span ng-repeat="btn in $ctrl.obj.buttons">' +
'<button class="btn" ng-click="$ctrl.changeProgress(btn, $ctrl.selectedProgressbar)">{{btn}}</button>' +
'</span>' +
'</div>',
controller: function () {
this.obj = {
"buttons": [
10,
38,
-13,
-18
],
"bars": [
62,
45,
62
],
"limit": 230
};
function changeProgressbar(val){
var val = parseInt(val);
var barValue = this.obj.bars[this.selectedProgressbar];
var selectedBar = this.selectedProgressbar;
var bars = this.obj.bars;
// this.obj.bars[0] = parseInt(this.obj.bars[0]) + parseInt(val);
// if we remove comment from above code and comment below one then progresbar value changes at same time
// but with below code its not changing at same time its changing when we click on any button or change progreebar selection
if(val > 0){
var total = parseInt(barValue) + val;
if (parseInt(barValue) > total) {
clearInterval(update);
}
else
{
barValue = total;
bars[selectedBar] = barValue;
}
}
}
this.changeProgress = changeProgressbar;
}
});
</script>
</body>
</html>
PLEASE RUN THE ABOVE SNIPPET
Here is a working DEMO

getJSON not working in Safari

Can someone help explain why the following code works in Chrome and IE, but not Safari. I believe the issue is somewhere with the getJSON. It is returning the JSON and works in other browsers, again just not safari. Thanks
Link to actual page: Link to actual page
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="author" content="Lenward Cunningham" />
<meta name="keywords" content="Louisiana Post Game Scores" />
<meta name="description" content="Post Game" />
<meta name="robots" content="all" />
<meta name="copyright" content="Lenward Cunningham" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
<title>Louisiana Post Game</title>
<link rel="apple-touch-icon" href="img/acadianaPGicon.png">
<link rel="stylesheet" type="text/css" href="assets/_styles.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<div id='header'><img src="img/acadianaPG200.jpg"></div>
<div id='content'></div>
<script type="text/javascript">
$(function() {
var url = "https://script.google.com/macros/s/AKfycbwFp0U_pYseCIXVUVfK_wOMoTgno76sk-JXDMGmPResdseOX3Xj/exec";
/*Populate list from JSON */
$.getJSON(url)
.done(function(data) {
for (var d in data) {
/*Process JSON Parameters*/
var game = data[d];
console.log(game)
if (game.matchup) {
var matchUp = game.matchup.split('\n');
var matchUp1 = matchUp[0];
var matchUp2 = matchUp[1];
}
var score1 = '';
var score2 = '';
if (game.score) {
var score = game.score.split('\n');
score1 = score[0];
score2 = score[1];
}
var gameStatus = game.gameStatus;
/*if (game.matchup === null || game.matchup === '')
continue;*/
$('#content').append(
"<div class='game'>"+
"<div class='team'><span class='rank'></span>"+matchUp1+"<span class='score'>"+score1+"</span></div>"+
"<div class='team'><span class='rank'></span>"+matchUp2+"<span class='score'>"+score2+"</span></div>"+
"<div class='status'>"+gameStatus+"</div>"+
"</div>"
);
}
})
});
</script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-51502655-1', 'googledrive.com');
ga('send', 'pageview');
</script>
</body>
</html>
Use this json format
$.getJSON(
"https://script.google.com/macros/s/AKfycbwFp0U_pYseCIXVUVfK_wOMoTgno76sk-JXDMGmPResdseOX3Xj/exec",
function (data) {
for (var d in data) {
/*Process JSON Parameters*/
var game = data[d];
console.log(game)
if (game.matchup) {
var matchUp = game.matchup.split('\n');
var matchUp1 = matchUp[0];
var matchUp2 = matchUp[1];
}
var score1 = '';
var score2 = '';
if (game.score) {
var score = game.score.split('\n');
score1 = score[0];
score2 = score[1];
}
var gameStatus = game.gameStatus;
/*if (game.matchup === null || game.matchup === '')
continue;*/
alert();
$('#content').append(
"<div class='game'>" +
"<div class='team'><span class='rank'></span>" + matchUp1 + "<span class='score'>" + score1 + "</span></div>" +
"<div class='team'><span class='rank'></span>" + matchUp2 + "<span class='score'>" + score2 + "</span></div>" +
"<div class='status'>" + gameStatus + "</div>" +
"</div>"
);
}
}
);

Categories

Resources