Create table column-headers dynamically - javascript

Right now I cannot figure out how to add headers for all the columns in this code where a html-table are created dynamically
function createTableAndInsert(sqlArray) {
//create table dynamically - only one row by the moment
var table = document.createElement('table');
for (var i = 1; i < 2; i++) {
var tr = document.createElement('tr'); // row
for (var j = 0; j < 8; j++) {
var td = document.createElement('td'); //column
var text = document.createTextNode(sqlArray[j]); //cell
td.appendChild(text);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById('single_fine_view').appendChild(table);
}

You can pass the header list separately to your function and add following code
function createTableAndInsert(sqlArray,headerList) {
var table = document.createElement('table');
var tr = document.createElement('tr'); // Header row
for (var j = 0; j < 8; j++) {
var th = document.createElement('th'); //column
var text = document.createTextNode(headerList[j]); //cell
th.appendChild(text);
tr.appendChild(th);
}
table.appendChild(tr);
for (var i = 1; i < 2; i++) {
var tr = document.createElement('tr'); // row
for (var j = 0; j < 8; j++) {
var td = document.createElement('td'); //column
var text = document.createTextNode(sqlArray[j]); //cell
td.appendChild(text);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById('single_fine_view').appendChild(table);
}

Your structure is:
<tr>
<td>
<div></div>
<div></div>
</td>
</tr>
thead should be appended before each row.
<thead></thead>
<tr>
<td>
<div></div>
<div></div>
</td>
</tr>
Solution:
var thead = document.createElement('thead');
thead.innerHTML = 'Header';
Before table.appendChild(tr);, add this line table.appendChild(thead);

THEAD needs one or more TR elements:
var table = document.createElement('table'); // 'table' may be a reserved word
var tblHead = document.createElement('thead');
var rowHead = document.createElement('tr');
table.appendChild(tblHead);
tblHead.appendChild(rowHead)
for(j=0; j<8; j++) {
var celHead = document.createElement('th');
//the array txtHeaders[] should be passed to your function if you have the values in advance
// otherwise, you can access the header cells later by:
// table.getElementsbyTagName('th')[].innerHTML
celHead.innerHTML = txtHeaders[j]
rowHead.appendChild(celHead)
}
// now do your row & table loops

Related

How can I set an image as an td background?

I'm trying to set each td as a different image that I have saved as imgn.gif. (n being image number, I have 13 images, img1.gif., img2.gif... img13.gif) I have a code that generates the table now I just can't figure out how to set a background image, preferably so that the n imgn.gif changes to the next index so the next td will have the next image.
this is the code that I have for now. I assume I have to set something differently here: const cellText = document.createTextNode(2);, so it sets background-image instead?
function options ()
{
const tbl = document.createElement("table");
const tblBody = document.createElement("tbody");
for (let i = 0; i < 1; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 16; j++) {
const cell = document.createElement("td");
const cellText = document.createTextNode(2);
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
document.body.appendChild(tbl);
}
just add 5 lines in you actual code:
options();
function options() {
const tbl = document.createElement("table");
const tblBody = document.createElement("tbody");
const nbImage = 13;
let curImage = 1;
for (let i = 0; i < 1; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 16; j++) {
const cell = document.createElement("td");
if (curImage > nbImage) {
curImage = 1;
}
cell.style.backgroundImage = 'url(img' + curImage + '.gif)';
const cellText = document.createTextNode(2);
cell.appendChild(cellText);
row.appendChild(cell);
curImage += 1;
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
document.body.appendChild(tbl);
}
I've added:
nbImage (13 from your post)
curImage to iterate through your 13 images
After your cell creation, checking the image number:
if (curImage > nbImage) {
curImage = 1;
}
So your fourteenth TD will have the image 1
Your is already created as a DOM element so you can refer it and add a background image:
cell.style.backgroundImage = 'url(img' + curImage + '.gif)';
That will add for each TD a backgound image "img1.gif", "img2.gif"... till "img13.gif", after "img1.gif" ... and so on...
You can create a variable (nImage for exemple) starting from 1 to 13 and reset it when up to 13 so it came back to 1. Then use this variable to modify style.backgroundImage of your td :
function options ()
{
const tbl = document.createElement("table");
const tblBody = document.createElement("tbody");
let nImage = 1 ;
for (let i = 0; i < 1; i++) {
const row = document.createElement("tr");
for (let j = 0; j < 16; j++) {
const cell = document.createElement("td");
const cellText = document.createTextNode(2);
if (nImage > 13){nImage =1 ;}
cell.style.backgroundImage = "url('yourPathTo/img"+nImage + ".gif')" ;
nImage++ ;
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
document.body.appendChild(tbl);
}

how to loop an array and get only the value of a particular index

I am building a dynamic table where i want only 3 values from my json to display and make one a link which when clicked on, the rest displays. Below is my code kindly assist please.
var myInvestment =[
{
"investmentNo":"00032",
"amount":"70000",
"status": "Expired",
"repayAmt":"70500",
"description": "Official",
"maturityDate":"2020-10-31"
},
{
"investmentNo":"00034",
"amount":"5000",
"status": "Current",
"repayAmt":"6000",
"description": "School fees",
"maturityDate":"2022-03-31"
}
]
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.createElement("tHead");
// CREATE ROW FOR TABLE HEAD .
var hRow = document.createElement("tr");
// 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=="Current") {
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);
}
}
This is my modal function that will display the second table
function invModalView(k,myInvestment){
var modal = document.getElementById("modal-block-normal");
modal.style.display = "block";
var investNo = document.getElementById("investNo");
var investmentTableModal = document.querySelector("#investmentTableModal");
myInvestment
.forEach((item, i) => {
var row = investmentTable.insertRow();
row.insertCell(0).innerHTML = item.repayAmt;
row.insertCell(1).innerHTML = item.description;
row.insertCell(2).innerHTML = item.maturityDate;
});
}
}
HTML
<table class="table table-bordered table-striped table-vcenter table-responsive" id="investmentTableModal">
<thead id="invtableHead">
<tr >
<th class="d-sm-table-cell" style="width: 30%;">Repayment Amount</th>
<td id="repayAmt"></td>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 30%;">Description</th>
<td id="description"></td>
</tr>
<tr>
<th class="d-sm-table-cell" style="width: 30%;">Maturity Date</th>
<td id = "matureDate"></td>
</tr>
</table>
i want when a user clicks on myInvestment.investmentNo[0], only the repaymentamt, description and maturityDate of myInvestment[0] will show
That's a lot of spaghetti code to go through, so I'm not even going to try.
In jQuery, what people normally do is they iterate over the array and construct each button, and then place each button on the dom. Then, they apply a $.click() on that button, and inside the .click callback they can create a clojure over the original item they created a button for.
like this: https://jsfiddle.net/0d8aL9xr/
var items = [{title: 'a bouncing ball', id: 1}, {title: 'a rubber duck', id: 2}];
items.forEach(item => {
const $newButton = $(`<button>${item.title}</button>`);
$('.buttons').append($newButton);
$newButton.click(function() {
$('#item-id').val(item.id);
$('#item-name').val(item.title);
})
})
function setSession(key,value){
window.localStorage.setItem(key, value);
}
function getSession(key){
return window.localStorage.getItem(key)
;
}
function unsetSession(key){
window.localStorage.removeItem(key)
;
}
////// Investment page scripts //////
function investmentData(){
var InvData = getSession("InvData");
var myInvestment = JSON.parse(InvData);
var investmentTable = document.querySelector("#investmentTable");
if(myInvestment.investments.length>0){
var col = []; // define an empty array
for (var i = 0; i < myInvestment.investments.length; i++) {
for (var key in myInvestment.investments[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.investments.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.investments[i][col[j]]+ '';
bRow.appendChild(td);
}else{
td.innerHTML = myInvestment.investments[i][col[j]];
bRow.appendChild(td);
}if (j==2) {
td.innerHTML = '<div class="badge">'+myInvestment.investments[i][col[j]]+ '</div>';
if (td.textContent=="Current") {
td.innerHTML = '<div class="badge badge-success">'+myInvestment.investments[i][col[j]]+ '</div>';
} else {
td.innerHTML = '<div class="badge badge-danger">'+myInvestment.investments[i][col[j]]+ '</div>';
}
}
tBody.appendChild(bRow)
}
investmentTable.appendChild(tBody);
}
}
}
function invModalView(k){
$('#investmentTableModal').empty();
var myInv = JSON.parse(getSession("InvData"));
var modal = document.getElementById("modal-block-normal");
modal.style.display = "block";
var investmentTableModal = document.querySelector("#investmentTableModal");
// CREATE TABLE BODY .
var tBody = document.createElement("tbody");
// // ADD COLUMN HEADER TO ROW OF TABLE HEAD.
// // Investment No
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "Investment No";
var td2 = document.createElement("td");
td2.style.width = "30%";
th.style.width = "30%";
td2.innerHTML = myInv.investments[k].investmentNo;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow);
investmentTableModal.appendChild(tBody)
// Investment duration
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "Duration";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].duration;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
// investment start date
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "startDate";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].startDate;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
// investment yield
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "Yield";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].yield;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
// investment repayment Amount
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "Repayment Amount";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].repayAmt;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
// investment description
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "Description";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].description;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
// investment maturityDate
var tBody = document.createElement("tbody");
var bRow = document.createElement("tr");
var th = document.createElement("th");
th.innerHTML = "MaturityDate";
var td2 = document.createElement("td");
td2.innerHTML = myInv.investments[k].maturityDate;
bRow.appendChild(th);
bRow.appendChild(td2);
tBody.appendChild(bRow)
investmentTableModal.appendChild(tBody);
}
////// Create Localstorage for MyInvestment ////
var myInvestment = '{"investments":[{"investmentNo":"00032","amount":"70000","status": "Expired","duration": "2","startDate": "2020-02-02","yield": "2.60","repayAmt":"70500","description": "Official","maturityDate":"2020-10-31"},{"investmentNo":"00033","amount":"40000","status": "Current","duration": "3","startDate": "2019-01-05","yield": "12.0","repayAmt":"42000","description": "Personal","maturityDate":"2020-12-31"},{"investmentNo":"00034","amount":"5000","status": "Current","duration": "4","startDate": "5-04-2008","yield": "20.0","repayAmt":"6000","description": "School fees","maturityDate":"2022-03-31"}]}'
setSession("InvData",myInvestment);
I later succeeded in getting this. i think it would be nice to share for someone out there who might need it.

Javascript : Creating a dynamic table with column title on the first row and row title in the first column

I am trying to create a table with title to be displayed on the first and second row and first column. The first row will have the same name which is working fine. But with my below script the row title (starting from 3rd row) displays in the last column than the first.
Please advise where am I going wrong with this.
var body = document.getElementsByTagName("body")[0];
var yardName = "B1";
var colsInYard = 5;
var rowsInYard = 5;
var tbl = document.createElement("table");
tbl.setAttribute("id", "our_table");
var tblHead = document.createElement("thead");
for (var r = 0; r < 1; r++) {
// creates a table row
var row = document.createElement("tr");
for (var c = 0; c <= colsInYard; c++) {
var cell = document.createElement("td");
if (c != 0) {
var cellText = document.createTextNode(yardName);
cell.appendChild(cellText);
row.appendChild(cell);
} else {
var cellText = document.createTextNode(" ");
cell.appendChild(cellText);
row.appendChild(cell);
}
}
tblHead.appendChild(row);
}
for (var r = 0; r < 1; r++) {
var row = document.createElement("tr");
for (var c = 0; c <= colsInYard; c++) {
var cell = document.createElement("td");
if (c != 0) {
var cellText = document.createTextNode(c);
cell.appendChild(cellText);
row.appendChild(cell);
} else {
var cellText = document.createTextNode(" ");
cell.appendChild(cellText);
row.appendChild(cell);
}
}
tblHead.appendChild(row);
}
tbl.appendChild(tblHead);
var tblBody = document.createElement("tbody");
for (var r = 1; r <= rowsInYard; r++) {
var row = document.createElement("tr");
var cellText = document.createTextNode(r);
for (var c = 0; c <= colsInYard; c++) {
var cell = document.createElement("td");
cell.appendChild(cellText);
row.appendChild(cell);
}
tblBody.appendChild(row);
}
tbl.appendChild(tblBody);
body.appendChild(tbl);
tbl.setAttribute("border", "0");
tbl.setAttribute("cellpadding", "0");
tbl.setAttribute("cellspacing", "0");
My fiddle https://jsfiddle.net/udopgxLv/1/
I believe you just need to add an IF statement to the code in the tbody section to get the data to post into the first column. I modified your jfiddle with the code below (just 2 lines added) and the values are inserted properly.
for (var r = 1; r <= rowsInYard; r++) {
var row = document.createElement("tr");
var cellText = document.createTextNode(r);
for (var c = 0; c <= colsInYard; c++) {
var cell = document.createElement("td");
if (c==1){ // <--- this was added
cell.appendChild(cellText);
} // <--- this was also added
row.appendChild(cell);
}
tblBody.appendChild(row);
}
You missed if statement in create tbody
for (var c = 0; c <= colsInYard; c++) {
var cell = document.createElement("td");
if (c=== 0)
cell.appendChild(cellText);
row.appendChild(cell);
}
https://jsfiddle.net/udopgxLv/3/

Creating a table with a loop

I'm quite new to Javascript and I'm trying to populate a table through a loop. The code works fine as long as I only try to populate the table, but when I try to add an IF condition in order to separate headers and data, it does not work any more. I would be curious to understand why it does not work and how can I solve the issue.
Below current broken code:
for(i = 0;i < values.length; i ++){
var table = document.getElementById("myTable");
tr = document.createElement('tr');
for (j = 0; j < values[i].length; j++) {
if (i=0) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
}
} else {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
}
}
Here the code that works without headers:
for(i = 0;i < values.length; i ++){
var table = document.getElementById("myTable");
tr = document.createElement('tr');
for (j = 0; j < values[i].length; j++) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
}
table.appendChild(tr);
}
you should put double equal i==0 not i=0
if (i==0) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
}
EDIT
in your second loup you should close the if statement and loop :
for (i = 0; i < values.length; i++) {
var table = document.getElementById("myTable");
tr = document.createElement('tr');
for (j = 0; j < values[i].length; j++) {
if (i == 0) {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
} else {
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = values[i][j];
}
}
}

Combine HTML Table Rows with Javascript

Is there an easy way to combine rows in an HTML table where the first column is the same? I basically have a table set up like:
<table>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
</table>
and I want it to generate:
<table>
<tr><td>test</td><td>37035</td><td>37035</td><tr>
<tr><td>test2</td><td>24690</td><td>24690</td><tr>
</table>
using jQuery:
var map = {};
$('table tr').each(function(){
var $tr = $(this),
cells = $tr.find('td'),
mapTxt = cells.eq(0).text();
if(!map[mapTxt]){
map[mapTxt] = cells;
} else {
for(var i=1, l=cells.length; i<l; i++){
var cell = map[mapTxt].eq(i);
cell.text(parseInt(cell.text()) + parseInt(cells[i].text()));
}
$tr.remove();
}
});
this is a "dumb" script -- no error handling for cases like different number of cells, fields being non-numeric, etc. Add those if necessary.
Also, depending on how it's generated, it's better to do this server-side.
Here's a plain JavaScript version.
window.onload = function() {
var table = document.getElementById('mytable');
var tr = table.getElementsByTagName('tr');
var combined = Array();
for (i = 0; i < tr.length; i++) {
var td = tr[i].getElementsByTagName('td');
var key = td[0].innerText;
if (!combined[key]) {//if not initialised
combined[key] = Array();
for (j = 0; j < td.length - 1; j++) combined[key][j] = 0;
}
for (j = 0; j < td.length - 1; j++)
combined[key][j] += parseInt(td[j + 1].innerText);
}
while (table.hasChildNodes()) table.removeChild(table.lastChild);
var tbody = document.createElement('tbody');//needed for IE
table.appendChild(tbody);
for (var i in combined) {
tr = document.createElement('tr');
tbody.appendChild(tr);
td = document.createElement('td');
td.innerText = i;
tr.appendChild(td);
for (j = 0; j < combined[i].length; j++) {
td = document.createElement('td');
td.innerText = combined[i][j];
tr.appendChild(td);
}
}
}
This will work on tables with any number of rows and any number of cells. I suppose you want to make the sum for every column, that's what this script does.
And as cwolves mentioned, it is more logical to do this serverside. Users that have JS disabled will see the not so clean uncombined table.

Categories