How adding a table with js? - javascript

I want add a table on my html table via JavaScript.
I've already tried using the appendChild and insertBefore methods, but those didn't work.
Here is my JavaScript:
var utilisateur = [{
id: 51,
checked: false,
prenom: "Dolores",
date: "Fermière",
examen: "host",
note: "ww.dolores#gmail.com"
}, {
id: 52,
checked: true,
prenom: "Bernard",
date: "Robopsycologue",
examen: "human",
note: "ww.bernard#gmail.com"
}
// {
// id: 3,
// name: "Robert",
// job: "Directeur",
// specie: "human",
// email: "ww.robert#gmail.com"
// },
// {
// id: 4,
// name: "Maeve",
// job: "Maquerelle",
// specie: "host",
// email: "ww.maeve#gmail.com"
// },
// {
// id: 5,
// name: "Teddy",
// job: "Inconnu",
// specie: "host",
// email: "ww.teddy#gmail.com"
// },
// {
// id: 6,
// name: "William",
// job: "Actionnaire",
// specie: "human",
// email: "ww.william#gmail.com"
// },
// {
// id: 7,
// name: "Elsie",
// job: "Programmeuse",
// specie: "human",
// email: "ww.elsie#gmail.com"
// },
// {
// id: 8,
// name: "Nathanael",
// job: "Dev",
// specie: "human",
// email: "s.nathanael#outlook.fr"
// }
];
for (let i = 0; i < 100; i++) {
var row = document.createElement("tr");
var cell0 = document.createElement("td");
var cell1 = document.createElement("td");
var atr = document.createAttribute("class");
atr.value = "bs-checkbox";
cell1.setAttributeNode(atr);
var para = document.createElement("input");
var para1 = document.createAttribute("data-index");
var para2 = document.createAttribute("name");
var para3 = document.createAttribute("type");
para1.value = "0";
para2.value = "btSelectItem";
para3.value = "checkbox";
para.setAttributeNode(para1);
para.setAttributeNode(para2);
para.setAttributeNode(para3)
cell1.appendChild(para);
// var cell1 = '<td class="bs-checkbox"></td>'
//alert(cell1).innerText;
var cell2 = document.createElement("td");
var cell3 = document.createElement("td");
var cell4 = document.createElement("td");
var cell5 = document.createElement("td");
var cell6 = document.createElement("td");
var cell7 = document.createElement("td");
var cell8 = document.createElement("td");
cell0.innerText = utilisateur[i].id;
cell1.innerText = utilisateur[i].checked
cell2.innerText = utilisateur[i].prenom;
cell3.innerText = utilisateur[i].date;
cell4.innerText = utilisateur[i].examen;
cell5.innerText = utilisateur[i].note;
row.appendChild(cell0);
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
row.appendChild(cell4);
row.appendChild(cell5);
// row.appendChild(cell6);
// row.appendChild(cell7);
// row.appendChild(cell8);
// document.getElementsById("tbody")[0].appendChild(row);
// var elem = document.getElementsById("tabs1");
// var mychild = document.getElementById("")
// elem.insertBefore(mypara, mychild);
// elem.appendChild(row);
var element = document.getElementById("tabs1")[0];
element.appendChild(row);
}
$(document).ready(function() {
$(cell1).toggleClass("bs-checkbox");
});
Here is my HTML:
<div class="tabs" id="tabs1">
<!-- <table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">#</th>
<th class="col">Name</th>
<th class="col">Job</th>
<th class="col">Attribut</th>
<th class="col">Email</th>
</tr>
</thead>
</table> -->
</div>
<table class="table" data-click-to-select="true" data-filter-control="true" data-search="true" data-show-export="true" data-toggle="table" data-toolbar="#toolbar" id="table">
<thead>
<tr>
<th id="0" style="visibility: hidden; display: none;"></th>
<th data-checkbox="true" data-field="state"></th>
<th data-field="prenom" data-filter-control="input" data-sortable="true">Prénom</th>
<th data-field="date" data-filter-control="select" data-sortable="true">Date</th>
<th data-field="examen" data-filter-control="select" data-sortable="true">Examen</th>
<th data-field="note" data-sortable="true">Note</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td id="1" style="visibility: hidden; display: none;"></td>
<td class="bs-checkbox"><input data-index="0" name="btSelectItem" type="checkbox"></td>
<td>Valérie</td>
<td>01/09/2015</td>
<td>Français</td>
<td>12/20</td>
</tr>
</tbody>
</table>
I want add my table JavaScript on my div on tbody, but he always go after my tbody.
The problem is, even if i create another div for my JavaScript, he never go on this div, so i want put my JavaScript on my div tabs1.

You cannot add a <div> inside a table body, so it is placed outside it, and so are your inserts. If you change this code:
var element = document.getElementById("tabs1")[0];
element.appendChild(row);
to this:
var element = document.getElementById("tbody");
element.appendChild(row);
it seems to work, somewhat. See: https://jsfiddle.net/KIKO_Software/kqr48uxj/4/
New rows are now added to the table body.

A number of issues...
You can't have a <div> as the child of a <tbody> because that is invalid HTML... so I would suggest you remove the <div> (also remember you can have multiple <tbody> tags within a <table> meaning you can split them up into section with separate id attributes, etc).
The function call of document.getElementById("tabs1") will return a single object, not an array - so you don't need the [0] at the end...
var element = document.getElementById("tabs1");
And lastly, you're going from 0 to 99 in your for loop, but the data you've provided only goes from 0 to 1 (or 0 to 7 with the commented out data)... however, you're trying to access utilisateur[i] and if the value of i is more than the number of items of data in the array, you will get an error in your developer console. So you need to check that there are enough items in utilisateur.length...
if (i < utilisateur.length) {
cell0.innerText = utilisateur[i].id;
cell1.innerText = utilisateur[i].checked
...
}
var utilisateur = [
{
id: 51,
checked: false,
prenom: "Dolores",
date: "Fermière",
examen: "host",
note: "ww.dolores#gmail.com"
},
{
id: 52,
checked: true,
prenom: "Bernard",
date: "Robopsycologue",
examen: "human",
note: "ww.bernard#gmail.com"
}
];
for (let i = 0; i < 100; i++) {
var row = document.createElement("tr");
var cell0 = document.createElement("td");
var cell1 = document.createElement("td");
var atr = document.createAttribute("class");
atr.value = "bs-checkbox";
cell1.setAttributeNode(atr);
var para = document.createElement("input");
var para1 = document.createAttribute("data-index");
var para2 = document.createAttribute("name");
var para3 = document.createAttribute("type");
para1.value = "0";
para2.value = "btSelectItem";
para3.value = "checkbox";
para.setAttributeNode(para1);
para.setAttributeNode(para2);
para.setAttributeNode(para3)
cell1.appendChild(para);
// var cell1 = '<td class="bs-checkbox"></td>'
//alert(cell1).innerText;
var cell2 = document.createElement("td");
var cell3 = document.createElement("td");
var cell4 = document.createElement("td");
var cell5 = document.createElement("td");
var cell6 = document.createElement("td");
var cell7 = document.createElement("td");
var cell8 = document.createElement("td");
if (i < utilisateur.length) {
cell0.innerText = utilisateur[i].id;
cell1.innerText = utilisateur[i].checked
cell2.innerText = utilisateur[i].prenom;
cell3.innerText = utilisateur[i].date;
cell4.innerText = utilisateur[i].examen;
cell5.innerText = utilisateur[i].note;
}
row.appendChild(cell0);
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
row.appendChild(cell4);
row.appendChild(cell5);
// row.appendChild(cell6);
// row.appendChild(cell7);
// row.appendChild(cell8);
// document.getElementsById("tbody")[0].appendChild(row);
// var elem = document.getElementsById("tabs1");
// var mychild = document.getElementById("")
// elem.insertBefore(mypara, mychild);
// elem.appendChild(row);
var element = document.getElementById("tbody");
element.appendChild(row);
}
$(document).ready(function(){
$(cell1).toggleClass("bs-checkbox");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table" class="table"
data-toggle="table"
data-search="true"
data-filter-control="true"
data-show-export="true"
data-click-to-select="true"
data-toolbar="#toolbar">
<thead>
<tr>
<th id="0" style="visibility: hidden; display: none;"></th>
<th data-field="state" data-checkbox="true"></th>
<th data-field="prenom" data-filter-control="input" data-sortable="true">Prénom</th>
<th data-field="date" data-filter-control="select" data-sortable="true">Date</th>
<th data-field="examen" data-filter-control="select" data-sortable="true">Examen</th>
<th data-field="note" data-sortable="true">Note</th>
</tr>
</thead>
<tbody id="tbody">
<tr>
<td id="1" style="visibility: hidden; display: none;"></td>
<td class="bs-checkbox "> <input data-index="0" name="btSelectItem" type="checkbox"> </td>
<td>Valérie</td>
<td>01/09/2015</td>
<td>Français</td>
<td>12/20</td>
</tr>
</tbody>
</table>

You can use a simple solution, using ES6 string interpolation
For example we have an array of objects
employees: [
{
name: 'John Doe',
phone: '00000000',
},
{
name: 'George Daniels',
phone: '11111111',
}
]
and a table html object.
you can append rows like this:
for (let employee of employees) {
let row = document.createElement("tr");
row.innerHTML = `<td>${employee.name}</td>
<td>${employee.phone}</td>`;
table.appendChild(row);
}

Related

Javascript loop table row working with rowspan and tr

I have table that need to custom with my JS in loop.
Below is the demo. What I need the final result is like this:
Is there any trick how to achieve as my result needed?
var jsonStr = {
  "data": [
    {
      "data2": [
        {
          "partNo": "ABC",
          "plan": "120"
        },
        {
          "partNo": "DEF",
          "plan": "50"
        }
      ],
      "lineID": "1"
    },
    {
      "data2": [
        {
          "partNo": "FAB",
          "plan": "75"
        }
      ],
"lineID": "2"
    }
  ]
};
for(var i=0; i<jsonStr.data.length; i++) {
var line = "LINE " + jsonStr.data[i].lineID;
var element = `<tr><td>${line}</td></tr>`;
$(".tbl1 tbody").append(element);
for(var j=0; j<jsonStr.data[i].data2.length; j++) {
var partNo = jsonStr.data[i].data2[j].partNo;
//console.log(partNo);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="tbl1" border="1">
<thead>
<th>Line</th>
<th>Part No.</th>
</thead>
<tbody></tbody>
</table>
<p>
It should be like this:
<table border="1">
<thead>
<th>Line</th>
<th>Part No.</th>
</thead>
<tbody>
<tr>
<td rowspan="2">LINE 1</td>
<td>ABC</td><tr>
<td>DEF</td>
</tr>
<tr>
<td rowspan="1">LINE 2</td>
<td>FAB</td>
</tr>
</tbody>
</table>
This is an approach using Array.forEach over the obj.data property to feed a target table tbody using the rowspan strategy.
Each time a new entry is visited in the new array, a new row is created and is given a rowspan value equal to the number of elements in its own data2 property array (partNo).
Then for each pf those, a new row is added, starting from the second one, holding the current partNo alone.
I didn't see you were using jQuery so I went for vanilla js. Anyway this is the MDN reference to the topics faced here:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td#attr-rowspan
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
var obj = {  
"data": [
{ 
"lineID": "1",
"data2": [{"partNo": "ABC","plan": "120"},{"partNo": "DEF","plan": "50"}],
},
{      
"lineID": "2",
"data2": [{"partNo": "FAB","plan": "75"}],
}
]
};
//target tbody
const tbody = document.querySelector('#tbl1 tbody');
//for each entry in obj.data
obj.data.forEach( entry => {
//create a new currentRow
let currentRow = document.createElement('tr');
//create a cell for the current line and append it to the currentRow
const tdLine = document.createElement('td');
tdLine.textContent = `LINE ${entry.lineID}`;
if(entry.data2.length > 1)
tdLine.setAttribute('rowspan', entry.data2.length);
currentRow.append(tdLine);
//for each partNo
entry.data2.forEach( (part, i) => {
//if the index of the current partNo is > 0, commit the currentRow and make a new one
if(i > 0){
tbody.append(currentRow);
currentRow = document.createElement('tr');
}
//create the cell for the current partNo and append it to the currentRow
const tdPart = document.createElement('td');
tdPart.textContent = part.partNo;
currentRow.append(tdPart);
});
//append the currentRow to the table
tbody.append(currentRow);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tbl1" class="tbl1" border="1">
<thead>
<th>Line</th>
<th>Part No.</th>
</thead>
<tbody></tbody>
</table>
Just set rowspan for the first cell of first group based on data2 length. Then render rest of group's rows with single cell with data2.
const jsonStr = {
"data": [
{
"data2": [
{
"partNo": "ABC",
"plan": "120"
},
{
"partNo": "DEF",
"plan": "50"
}
],
"lineID": "1"
},
{
"data2": [
{
"partNo": "FAB",
"plan": "75"
}
],
"lineID": "2"
}
]
};
const tbody = $(".tbl1").find("tbody");
for(let i=0; i<jsonStr.data.length; i++) {
const label = "LINE " + jsonStr.data[i].lineID;
let tr = document.createElement("tr");
tbody.append(tr);
let td = document.createElement("td");
td.innerHTML = label;
td.rowSpan = jsonStr.data[i].data2.length;
tr.appendChild(td);
td = document.createElement("td");
td.innerHTML = jsonStr.data[i].data2[0].partNo;
tr.appendChild(td);
for(let j=1; j<jsonStr.data[i].data2.length; j++) {
const partNo = jsonStr.data[i].data2[j].partNo;
tr = document.createElement("tr");
tbody.append(tr);
td = document.createElement("td");
td.innerHTML = partNo;
tr.appendChild(td);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="tbl1">
<tbody></tbody>
</table>

create table from jsp in javascript

I have the following table with the columns shown in the code below (in jsp).
I want this same table to be done in javascript, where list in my case will be a json array of objects.
Can you kindly help me with this?
<table border="1" width="90%">
<tr>
<th>Id</th>
<th>Name</th>
<th>Password</th>
<th>Email</th>
<th>Sex</th>
<th>Country</th>
<th>Edit</th>
<th>Delete</th></tr>
<c:forEach items="${list}" var="u">
<tr><td>${u.getId()}</td>
<td>${u.getName()}</td>
<td>${u.getPassword()}</td>
<td>${u.getEmail()}</td>
<td>${u.getSex()}</td>
<td>${u.getCountry()}</td>
<td>Edit</td>
<td>Delete</td></tr>
</c:forEach>
</table>
The most simplest thing you can try is something like that (if i understood you correctly):
let table = document.getElementById("my-table");
let list = [{
"id":1,
"name":"Jhon",
"password":"doejhon#",
"email":"jhondoe#doe.com",
"sex":"male",
"country":"USA"
},
{
"id":2,
"name":"Lisa",
"password":"w87e8c8787%",
"email":"lisa#doe.com",
"sex":"female",
"country":"UK"
}];
list.forEach(item=>{
let child = document.createElement("tr");
child.innerHTML = `<td>${item.id}</td><td>${item.name}</td><td>${item.password}</td><td>${item.email}</td><td>${item.sex}</td><td>${item.country}</td><td>-</td><td>-</td>`;
table.appendChild(child);
})
<table border="1" width="90%" id="my-table">
<tr>
<th>Id</th>
<th>Name</th>
<th>Password</th>
<th>Email</th>
<th>Sex</th>
<th>Country</th>
<th>Edit</th>
<th>Delete</th></tr>
</table>
<!--
<c:forEach items="${list}" var="u">
<tr><td>${u.getId()}</td>
<td>${u.getName()}</td>
<td>${u.getPassword()}</td>
<td>${u.getEmail()}</td>
<td>${u.getSex()}</td>
<td>${u.getCountry()}</td>
<td>Edit</td>
<td>Delete</td></tr>
</c:forEach>
-->
Here is one approach, demoing with a smaller set of fields.
It is not entirely clear what the links for Edit/Delete are supposed to be. Here, we leave it as a link to a JSP.
let table = document.createElement('TABLE');
let header = document.createElement('TR');
let fields = [ 'Id', 'Name', 'Password', 'Edit' ];
let cell;
for (var i=0; i<fields.length; i++) {
cell = document.createElement('TH');
cell.innerHTML = fields[i];
header.appendChild(cell);
}
table.appendChild(header);
let data = [
{
'Id': 'someId',
'Name': 'some name',
'Password': 'some encrypted password',
'Edit': "<a href='editform.jsp?id=someId'>Edit</a>"
},
{
'Id': 'anotherId',
'Name': 'some other name',
'Password': 'some other encrypted password',
'Edit': "<a href='editform.jsp?id=anotherId'>Edit</a>"
}
];
let rowData;
let fieldName;
for (i=0 ; i<data.length ; i++) {
let row = document.createElement('TR');
rowData = data[i];
for (var j=0; j<fields.length; j++) {
fieldName = fields[j];
cell = document.createElement('TD');
cell.innerHTML = rowData[fieldName];
row.appendChild(cell);
}
table.appendChild(row);
}
let body = document.querySelector('BODY');
body.appendChild(table);

What am I doing wrong in creating this dynamically generated table?

Apologies for any simple mistakes, this is my first Stack Overflow post and I'm relatively new to coding.
I am attempting to create a website that displays a dynamically generated table using DOM elements. This table's rows and columns have been defined using DOM elements, and it should now populate itself on page load when storeItemOutput() is called from initialize(). It should be pulling the data from a loop through the previously defined and populated array storeItems, and displaying their attributes in the table id "storeItemOutput". It should also get one of five values from a dropdown box, and display items that match the selected category whenever it is changed.
However, I can't get the table itself or it's contents to actually display on the page. I'm unsure what is preventing this, and the lack of any output has left me stumped. Am I missing some code in my function? Is the table not created properly?
I've included parts of my code below, as well as expected output and actual output to try and help you understand my issue.
<select class="categoryDropDown" style="margin: 30px;">
<p>
<option selected value="All" onload="storeItemOutput();">All</option>
<option value="Tops" onchange="storeItemOutput();">Tops</option>
<option value="Bottoms" onchange="storeItemOutput();">Bottoms</option>
<option value="Shoes" onchange="storeItemOutput();">Shoes</option>
<option value="Accessories" onchange="storeItemOutput();">Accessories</option>
</p>
</select>
<table id="storeItemOutput">
<span><strong>| ID | Product Name | Price | Qty | Max | Category | Image |</strong></span>
</br>
<tbody>
<tr>
<th>b</th>
<th>b</th>
<th>b</th>
<th>b</th>
<th>b</th>
<th>b</th>
<th>b</th>
</tr>
<tr>
<td>b</td>
<td>b</td>
<td>b</td>
<td>b</td>
<td>b</td>
<td>b</td>
<td>b</td>
</tr>
</tbody>
(Output all store items via DOM table here)
</table>
This is some of my HTML code with an ID'd dummy table, and a dropdown menu class.
var storeItems = [];
function StoreItem(id, name, price, qtyOnHand, maxPerCust, category, shipping, reviews, description, image) {
this.id = id; //String
this.name = name; //String
this.price = price; //Number
this.qtyOnHand = qtyOnHand; //Number
this.maxPerCust = maxPerCust; //Number
this.category = category; //String
this.shipping = shipping; //Number
this.reviews = reviews; //Array
this.description = description; //String
this.image = image; //String
}
storeItems.push(new StoreItem("Y2k111", "Black Hoodie", 119.99, 10, 1, "Tops", 19.99, this.reviews, "100% Cotton Hoodie in Black", "/img/home_img/link"));
Some Javascript code of creating an empty array for store items, creating an object constructor for store items, and pushing a new item to the array (normally there is more than one item being pushed, I used just one here to save space).
function storeItemOutput() {
var itemTableDiv = document.getElementById("cartItemOutput");
var table = document.createElement("table");
itemTableDiv.innerHTML = "";
document.getElementsByTagName("tbody")[0].remove();
var tBody = document.createElement("tbody");
var headerRow = document.createElement("tr");
var hC1 = document.createElement("th");
var hC2 = document.createElement("th");
var hC3 = document.createElement("th");
var hC4 = document.createElement("th");
var hC5 = document.createElement("th");
var hC6 = document.createElement("th");
var hC7 = document.createElement("th");
hC1.innerHTML = "Item ID";
hC2.innerHTML = "Item Name";
hC3.innerHTML = "Item Price";
hC4.innerHTML = "Item Quantity";
hC5.innerHTML = "Max Items Per Customer";
hC6.innerHTML = "Category";
hC7.innerHTML = "Image";
headerRow.appendChild(hC1);
headerRow.appendChild(hC2);
headerRow.appendChild(hC3);
headerRow.appendChild(hC4);
headerRow.appendChild(hC5);
headerRow.appendChild(hC6);
headerRow.appendChild(hC7);
tbody.appendChild(headerRow);
for (var index = 0; index < storeItems.length; index++) {
var products = storeItems[i];
var theRow = document.createElement("tr");
var c1 = document.createElement("td");
var c2 = document.createElement("td");
var c3 = document.createElement("td");
var c4 = document.createElement("td");
var c5 = document.createElement("td");
var c6 = document.createElement("td");
var c7 = document.createElement("td");
c1.innerHTML = products.id;
c2.innerHTML = products.name;
c3.innerHTML = "$" + products.price.toFixed(2);
c4.innerHTML = products.qtyOnHand;
c5.innerHTML = products.maxPerCust;
c6.innerHTML = products.category;
c7.innerHTML = products.image;
theRow.appendChild(c1);
theRow.appendChild(c2);
theRow.appendChild(c3);
theRow.appendChild(c4);
theRow.appendChild(c5);
theRow.appendChild(c6);
theRow.appendChild(c7);
tbody.appendChild(theRow);
}
itemTableDiv.appendChild(tbody);
var selectedCategory = document.getElementByClass("categoryDropDown").value;
var filteredItems = [];
var index = 0;
while (index < storeItems.length) {
if (storeItems[index].category == selectedCategory) {
filteredItems.push(storeItems[index]);
}
index++;
}
storeItemOutput(filteredItems);
And finally, my function that is meant to create and populate the table, before displaying the items that match the selected category.
Here is an image of what the table should look like:
working table
And the lack of output for my table:
my missing table
Any help would be appreciated.
Here's a working example. A few things worthy of mention:
I've used a template element, since it makes repeatedly creating
similar content very much faster.
Floating-point math has rounding errors. For this reason, I've stored the
prices in cents rather than dollars. Perform all math on the number
of cents, then present it as dollars & cents
A NodeList is very similar to, but slightly different than an array. It does not for instance have a forEach member function. For this reason, I used Array.from in the appendRow function. (which is actually shorter by 1 line if you use the commented code instead)
"use strict";
function newEl(tag) {
return document.createElement(tag)
}
function byId(id) {
return document.getElementById(id)
}
function qs(sel, parent = document) {
return parent.querySelector(sel)
}
function qsa(sel, parent = document) {
return parent.querySelectorAll(sel)
}
window.addEventListener('load', onLoaded, false);
function onLoaded(evt) {
var tableData = [
["PID01", "Fluffy Bear", 599, 600, 20, "Toy", "bear.png"],
["PID02", "Rubber Ducky", 1599, 40, 5, "Toy", "duck.png"],
["PID03", "Cool Handbag", 599, 1, 2, "Fashion", "bag.png"],
["PID04", "Fidget Spinner", 999, 120, 10, "Toy", "spinner.png"],
["PID05", "Lame Handbag", 4599, 60, 3, "Fashion", "bag.png"],
["PID06", "UltraMega Genuine Laptop", 170599, 20, 2, "Technology", "laptop.png"],
];
populateTable(tableData);
var categoryNames = ["All", "Fashion", "Toy", "Technology"];
populateSelect(byId('catSelector'), categoryNames);
qs('select').addEventListener('change', updateFilter, false);
}
function populateSelect(selElem, data) {
selElem.innerHTML = '';
data.forEach(txt => selElem.appendChild(new Option(txt, txt)));
}
function populateTable(data) {
data.forEach(appendRow);
function appendRow(itemData, itemIndex, items) {
let newRow = byId('productRowTemplate').content.cloneNode(true);
let cells = Array.from(newRow.firstChild.cells);
cells.forEach((cell, index) => {
if (index == 2)
cell.textContent = '$' + (itemData[index] / 100).toFixed(2);
else
cell.textContent = itemData[index];
});
// cells[0].textContent = itemData[0];
// cells[1].textContent = itemData[1];
// cells[2].textContent = '$'+(itemData[2]/100).toFixed(2);
// cells[3].textContent = itemData[3];
// cells[4].textContent = itemData[4];
// cells[5].textContent = itemData[5];
byId('storeItemOutput').tBodies[0].appendChild(newRow);
}
}
function updateFilter() {
let filter = byId('catSelector').value;
let prodRows = qsa('#storeItemOutput > tbody > tr');
if (filter == 'All') {
prodRows.forEach(row => row.classList.remove('notShown'));
} else {
prodRows.forEach(
row => {
if (row.cells[5].textContent == filter)
row.classList.remove('notShown');
else
row.classList.add('notShown');
}
);
}
}
.notShown {
display: none;
}
.price,
.qty,
.max {
text-align: right;
}
<template id='productRowTemplate'><tr>
<td class='id'></td>
<td class='name'></td>
<td class='price'></td>
<td class='qty'></td>
<td class='max'></td>
<td class='cat'></td>
<td><img class='icon'/></td>
</tr></template>
<body>
Filter:
<select id='catSelector'></select>
<table id='storeItemOutput'>
<thead>
<tr>
<th>ID</th>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Max</th>
<th>Category</th>
<th>Image</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>

I have a long json that i want to be displayed only four when the page loads and shows the rest when a user clicks on the investment link

I have a long json that i want to be displayed only four when the page loads and shows the rest when a user clicks on the investment link.
This is my investment table
<table class="table table-bordered table-striped table-vcenter js-dataTable-full-pagination table-responsive" id="investmentTable">
<thead id="tableHead">
<tr id="tableRow">
<th class="text-center" style="width: 30%;" id="serialNo">S/N</th>
<th class="d-sm-table-cell" style="width: 30%;" id="investmentNo">Investment No</th>
<th class="d-sm-table-cell" style="width: 30%;" id="amount">Amount</th>
<th class="d-sm-table-cell" style="width: 30%;" id="status">Status</th>
</tr>
</thead>
</table>
This is the Json test and code
// Call for Investment Api
function investmentData(){
var myInvestment = [
{
"investmentNo":"00032",
"amount":"70000",
"status": "Expired",
"duration": "2",
"startDate": "7-02-2020",
"yield": "2.60",
"repayAmt":"70500",
"description": "Official"
},
{
"investmentNo":"00033",
"amount":"40000",
"status": "Current",
"duration": "3",
"startDate": "4-01-2019",
"yield": "12.0",
"repayAmt":"42000",
"description": "Personal"
},
{
"investmentNo":"00034",
"amount":"5000",
"status": "Current",
"duration": "4",
"startDate": "5-04-2008",
"yield": "20.0",
"repayAmt":"6000",
"description": "School fees"
}
]
var investmentTable = document.querySelector("#investmentTable");
if(myInvestment.length>0){
var col = []; // define an empty array
for (var i = 0; i < myInvestment.length; i++) {
for (var key in myInvestment[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
// CREATE TABLE HEAD .
var tHead = document.querySelector("#tableHead");
// CREATE ROW FOR TABLE HEAD .
var hRow = document.querySelector("#tableRow");
// ADD COLUMN HEADER TO ROW OF TABLE HEAD.
tHead.appendChild(hRow);
investmentTable.appendChild(tHead);
// CREATE TABLE BODY .
var tBody = document.createElement("tbody");
// ADD COLUMN HEADER TO ROW OF TABLE HEAD.
for (var i = 0; i < myInvestment.length; i++) {
var bRow = document.createElement("tr");
// CREATE ROW FOR EACH RECORD .
var td = document.createElement("td");
td.innerHTML = i+1;
bRow.appendChild(td);
for (var j = 0; j < 3; j++) {
var td = document.createElement("td");
if (j==0) {
td.innerHTML = ''+myInvestment[i][col[j]]+ '';
bRow.appendChild(td);
}else{
td.innerHTML = myInvestment[i][col[j]];
bRow.appendChild(td);
}if (j==2) {
td.innerHTML = '<div class="badge">'+myInvestment[i][col[j]]+ '</div>';
if (td.textContent=="Expired") {
td.innerHTML = '<div class="badge badge-success">'+myInvestment[i][col[j]]+ '</div>';
} else {
td.innerHTML = '<div class="badge badge-danger">'+myInvestment[i][col[j]]+ '</div>';
}
}
}
tBody.appendChild(bRow)
}
investmentTable.appendChild(tBody);
var link = document.getElementsByTagName('a');
for(x=0;x<link.length;x++){
link[x].onclick = function invModalView(k){
var href = this.getAttribute("href");
var modal = document.getElementById("modal-block-normal");
modal.style.display = "block";
var investNo = document.getElementById("investNo");
var investmentTableModal = document.querySelector("#investmentTableModal");
if(myInvestment.length>0){
var col = []; // define an empty array
for (var i = 0; i < myInvestment.length; i++) {
for (var key in myInvestment[i]) {
if (col.indexOf(key) === -1) {
col.push(key);
}
}
}
// CREATE TABLE BODY .
var tBody = document.createElement("tbody");
// ADD COLUMN HEADER TO ROW OF TABLE HEAD.
for (var k = 3; k < 7; k++){
var bRow = document.createElement("tr");
for (var i = 0; i < myInvestment.length; i++) {
// CREATE ROW FOR EACH RECORD .
var td = document.createElement("td");
td.innerHTML = myInvestment[i][col[k]];
bRow.appendChild(td);
}
tBody.appendChild(bRow)
}
investmentTableModal.appendChild(tBody);
}
};
}
}
}
**This is the modal table**
<table class="table table-bordered table-striped table-vcenter table-responsive" id="investmentTableModal">
<thead id="tableHeadModal">
<tr>
<th class="d-sm-table-cell" style="width: 40%;">Investment No</th>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 35%;">Duration</th>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 40%;">StartDate</th>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 40%;">Yield</th>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 40%;">RepaymentAmount</th>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 40%;">Description</th>
</tr>
</thead>
</table>
The image is where the problem lies. it displays all values at once when i only want it to display the first array from index 3-7 in a row when a user clicks on the first link.

How do I display a dynamically created html table only once?

Each time I input another football score, the league table is updated and displayed but it's appended to a list of tables. How do I display only the latest table?
Here is an extract of the html:
<div>
<table id="matches" border="1"> </table>
</div>
<div>
<table id="standings" border="1"> </table>
</div>
<input type="button" value="Update" onclick="update()" />
Here is the javascript that displays the fixtures for inputting scores:
// Display fixtures to input the scores
window.onload = function()
{
table = document.getElementById("matches");
var row;
var cell1;
var cell2;
var cell3;
for (i = 1; i < Results.length; i++)
{
row = table.insertRow(i-1); //table starts row 0 but Results row 1 so i-1 used
cell1 = row.insertCell(0);
cell2 = row.insertCell(1);
cell3 = row.insertCell(2);
cell4 = row.insertCell(3);
cell1.innerHTML = Results[i][0];
cell2.innerHTML = '<input type="number" min="0" max="99"/>'
cell3.innerHTML = '<input type="number" min="0" max="99"/>'
cell4.innerHTML = Results[i][3];
}
}
And here is the code that displays the table after the lastest scores have been inputed:
// Display League Table
standings = document.getElementById("standings");
for (i = 0; i < League.length; i++)
{
row = standings.insertRow(i);
cell1 = row.insertCell(0);
cell2 = row.insertCell(1);
cell3 = row.insertCell(2);
cell4 = row.insertCell(3);
cell5 = row.insertCell(4);
cell6 = row.insertCell(5);
cell7 = row.insertCell(6);
cell8 = row.insertCell(7);
cell1.innerHTML = League[i][0];
cell2.innerHTML = League[i][1];
cell3.innerHTML = League[i][2];
cell4.innerHTML = League[i][3];
cell5.innerHTML = League[i][4];
cell6.innerHTML = League[i][5];
cell7.innerHTML = League[i][6];
cell8.innerHTML = League[i][7];
}
After entering three scores this is what is displayed:
I've tried clearing the league array within javascript but still the same outcome. How do I only display top version of the table? Thanks
Thanks again to comments, and some further googling, the following deletes the table ahead of updating it, unless there's a better way?
for(var i = standings.rows.length - 1; i >= 0; i--)
{
standings.deleteRow(i);
}
Cheers everyone! :)
For your table update/question, focus on the updateRow function. This line does the actual update of contents of row rownum column(<td>) i
rows[rownum].getElementsByTagName('td')[i].innerHTML = coldata[i];
There is more here than just updating the table rows, for that you can review the function updateRow in my name-spaced object. updateRow calls createRow if it needs to (the row at that index does not exist), nothing fancy here, then updates the new row.
I use the array of match objects in matches I created (was not one in the question so I made assumptions) also in the namespace:
matches: [{
match: 1,
score: [{
team: "Ap",
score: 3
}, {
team: "Or",
score: 2
}]
}],
Note where I call this code to update the table for standings in the table with standings-table id. I have no idea what those are so I simply inserted some stuff in the array then update the table using
for (let i = 0; i < myLeague.standings.length; i++) {
myLeague.updateRow('standings-table', myLeague.standings[i], i);
}
Other things: I created the form simply to show how to update the table when a new match is inserted, I trigger an event and it does what it needs to update or insert a row - but really that is just to test the update as new matches are created.
Row in a table are either updated or inserted depending totally on the array of matches content
nothing handles deletions from the table or array since this was just about insert and update
if a row index for a match index does not exist, it creates a new row and updates it
var myLeague = myLeague || {
teamSelect1: "team1",
teamSelect2: "team2",
matchesPlayed: 1,
teams: [{
name: "Apples",
abbreviation: "Ap"
},
{
name: "Oranges",
abbreviation: "Or"
},
{
name: "Pears",
abbreviation: "Pe"
}
],
matches: [{
match: 1,
score: [{
team: "Ap",
score: 3
}, {
team: "Or",
score: 2
}]
}],
standings: [
["A", 2, 1, 1, 3, 2, 3, 0],
["B", 3, 1, 1, 3, 2, 3, 6]
],
cloneRow: function(tableid, objectRef) {
// find table to clone/append to
let table = document.getElementById(tableid);
// find row to clone, I use first one
let firstRow = mytable.rows[0];
// let row = document.getElementById("rowToClone");
let clone = firstRow.cloneNode(true); // copy children too
clone.id = ""; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
},
createRow: function(tableid, colCount, rowCount = 1, defaultContent = "") {
let row = document.createElement('tr'); // create row node
for (let i = 0; i < colCount; i++) {
let newText = document.createTextNode(defaultContent);
let col = row.insertCell(i);
col.appendChild(newText);
}
let table = document.getElementById(tableid); // find table to append to
let tbody = table.getElementsByTagName('tbody')[0];
for (let r = 1; r <= rowCount; r++) {
tbody.appendChild(row); // append row to table
}
},
updateRow: function(tableid, coldata = ['$nbsp;'], rownum = 0) {
let table = document.getElementById(tableid); // find table to update to
let tbody = table.getElementsByTagName('tbody')[0];
let rows = tbody.rows; // get rows node
let maxRows = 20; //keep it from going crazy adding rows
while (rows.length < maxRows && !rows[rownum]) {
this.createRow(tableid, coldata.length, 1, "x");
}
//myLeague.updateRow(tableid,coldata, rownum);
for (let i = 0; i < coldata.length; i++) {
rows[rownum].getElementsByTagName('td')[i].innerHTML = coldata[i];
}
},
addTeam: function(team, teamid) {
var sel = document.getElementById(teamid);
var optNew = document.createElement("option");
optNew.value = team.abbreviation;
optNew.text = team.name;
sel.add(optNew, null);
},
addTeamsToSelect: function() {
myLeague.teams.forEach(function(team) {
myLeague.addTeam(team, this.teamSelect1);
myLeague.addTeam(team, this.teamSelect2);
}, this);
},
listMatches: function(event) {
// event.target is the div
let src = event.target.dataset.source;
console.log("src:", src);
document.getElementById("matchplayed").textContent = event.matches;
this[src].forEach(function(item, index, array) {
document.getElementById('matchplayed').textContent = array.length;
let rowdata = [item.score[0].team, item.score[0].score, item.score[1].team, item.score[1].score];
this.updateRow(src, rowdata, index);
}, this);
},
clickAddListener: function(event) {
// 'this' is bound to the namespace object
// console.log(event.target); // the button
// console.log(this.matchesPlayed);//namespace
if (!document.getElementById(this.teamSelect1).value || !document.getElementById(this.teamSelect2).value) {
let errorEl = document.getElementById("form1")
.getElementsByClassName("error-text")[0];
errorEl.textContent = "Both teams need to be selected.";
errorEl.style.visibility = 'visible';
errorEl.style.opacity = '1';
setTimeout(function() {
errorEl.style.WebkitTransition = 'visibility .5s, opacity .5s';
errorEl.style.opacity = '0';
errorEl.style.visibility = 'hidden';
errorEl.textContent = "";
}, 5000);
} else {
this.matchesPlayed++;
let r = {
match: this.matchesPlayed,
score: [{
team: document.getElementById(this.teamSelect1).value,
score: document.getElementById("score1").value
}, {
team: document.getElementById(this.teamSelect2).value,
score: document.getElementById("score2").value
}]
};
this.matches.push(r);
}
document.getElementById('matches').dispatchEvent(this.showmatchesevent);
},
addListeners: function() {
let scope = this;
document.getElementById(this.teamSelect1)
.addEventListener('change', function() {
let s = document.getElementById(scope.teamSelect2);
let oval = s.value;
if (this.value == oval) {
s.value = '';
}
}, this);
document.getElementById(this.teamSelect2)
.addEventListener('change', function() {
let s = document.getElementById(scope.teamSelect1);
let oval = s.value;
if (this.value == oval) {
s.value = '';
}
}, this);
document.getElementById('add-match')
// bind this namespace to the event listener function
.addEventListener('click', (this.clickAddListener).bind(this), false);
this.showmatchesevent = new CustomEvent('showmatches');
document.getElementById('matches')
.addEventListener('showmatches', this.listMatches.bind(this), false);
}
};
window.onload = function() {
myLeague.addTeamsToSelect();
myLeague.addListeners();
for (let i = 0; i < myLeague.standings.length; i++) {
myLeague.updateRow('standings-table', myLeague.standings[i], i);
}
// set table from defaults/imported list
document.getElementById('matches').dispatchEvent(myLeague.showmatchesevent);
};
/* typography */
html {
font-family: 'helvetica neue', helvetica, arial, sans-serif;
}
th {
letter-spacing: 2px;
}
td {
letter-spacing: 1px;
}
tbody td {
text-align: center;
}
.match-inputs {
border: solid 2px #DDDDDD;
padding;
1em;
margin: 1em;
}
.error-text {
height: 1em;
color: red;
}
.matches-played {
padding: 13m;
}
/* table layout */
table {
border-collapse: collapse;
border: 1px solid black;
}
.score th,
td {
padding: 0.2em;
border: solid #DDDDDD 1px;
}
.container {
padding: 1em;
}
<div class="container match-inputs">
<form id="form1">
<div>Add Matches</div>
<div class="input-group"><label>Choose L Team:</label>
<select id="team1">
<option value="">Choose</option>
</select>
</div>
<div class="input-group"><label>Choose L2 Team:</label>
<select id="team2">
<option value="">Choose</option>
</select>
</div>
<div class="input-group score-group"><label>Team1 score:</label>
<input id="score1" type="number" class="score-input" value="0" min="0" max="99" value="0" />
</div>
<div class="input-group score-group"><label>Team2 score:</label>
<input id="score2" type="number" class="score-input" value="0" min="0" max="99" value="0" />
</div>
<div class="input-group"><label>Add this match to the list.</label>
<button type="button" id="add-match">Add Match</button>
</div>
<div class="error-text"> </div>
</form>
</div>
<div class="container">
<div class="matches-played">Matches Played:<span id="matchplayed"></span></div>
<table id="matches" data-source="matches">
<thead>
<tr>
<th colspan="4">Matches</th>
</tr>
<tr>
<th>L</th>
<th>S</th>
<th>S2</th>
<th>L1</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="container">
<table id="standings-table">
<thead>
<tr>
<th colspan="8">Standings</th>
</tr>
<tr>
<th>Team</th>
<th>P</th>
<th>W</th>
<th>D</th>
<th>L</th>
<th>F</th>
<th>A</th>
<th>Pts</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>

Categories

Resources