I am working on Javascript. I have some API calls (using AJAX) in my code. There is a button in my UI say USER DASHBOARD. On click of this button I am making some API calls using AJAX and displaying HTML UI that has the table with rows in it.
In the table above there are two rows. If I close this popup and then again click on USER DASHBOARD button it will append those two rows again in the table. I don't want to append those rows again.
My code to form table using AJAX response looks like below:
getUserAccountDetailsCallback: function (userid, appid, response) {
if (response != "") {
var res = JSON.parse(response);
var totalNoOfApps = document.getElementById('totalSites');
var totalNoOfSubscriptions = document.getElementById('totalSubscribers');
totalNoOfApps.innerHTML = res.totalNoOfApps;
totalNoOfSubscriptions.innerHTML = res.totalNoOfSubscriptions;
if (res.subscriptionsForCurrentAppId.length > 0) {
for (var i = 0; i < res.subscriptionsForCurrentAppId.length; i++) {
var td1 = document.createElement('td');
td1.style.width = '30';
td1.innerHTML = i + 1;
var td2 = document.createElement('td');
td2.innerHTML = res.subscriptionsForCurrentAppId[i].gatewayName;
var td3 = document.createElement('td');
td3.innerHTML = res.subscriptionsForCurrentAppId[i].priceCurrencyIso;
var td4 = document.createElement('td');
td4.innerHTML = res.subscriptionsForCurrentAppId[i].amountPaid;
var date = new Date(res.subscriptionsForCurrentAppId[i].subscribedDate);
date.toString();
var td5 = document.createElement('td');
td5.innerHTML = date.getMonth() + 1 + '/' + date.getDate() + '/' + date.getFullYear(); //res.subscriptionsForCurrentAppId[i].subscribedDate;
var td6 = document.createElement('td');
td6.innerHTML = res.subscriptionsForCurrentAppId[i].transactionId;
var td7 = document.createElement('td');
td7.innerHTML = res.subscriptionsForCurrentAppId[i].active;
var tr = document.createElement('tr');
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.appendChild(td4);
tr.appendChild(td5);
tr.appendChild(td6);
tr.appendChild(td7);
var table = document.getElementById('tbl');
table.appendChild(tr);
}
}
}
}
Please help. Where I am doing wrong.
To clean your table, you need to set its HTML content to empty.
Something like this:
var table = document.getElementById('tbl');
table.innerHTML = "";
After that, add your new rows.
You need to empty your table before appending any data to it.
Therefore add this line
table.innerHTML = '';
before table.appendChild(tr); in your code.
This empties your table everytime the function is called.and then append 's new data to it.
If there are any bugs please reply i am happy to help,
Utkarsh Vishnoi
Related
function CreateWeakHeader(name) {
var tr = document.createElement('tr');
var td = document.createElement('td');
td.classList.add("cal-usersheader");
td.style.color = "#000";
td.style.backgroundColor = "#7FFF00";
td.style.padding = "0px";
td.appendChild(document.createTextNode(name));
tr.appendChild(td);
var thh = document.createElement('td');
thh.colSpan = "31";
thh.style.color = "#FFFFFF";
thh.style.backgroundColor = "#7FFF00";
tr.appendChild(thh);
return tr;
}
function htmlTable(data, columns) {
var header = document.createElement("div");
header.classList.add("table-responsive");
var header2 = document.createElement("div");
header2.id = "calplaceholder";
header.appendChild(header2);
var header3 = document.createElement("div");
header3.classList.add("cal-sectionDiv");
header2.appendChild(header3);
if ((!columns) || columns.length == 0) {
columns = Object.keys(data[0]);
}
var tbe = document.createElement('table');
tbe.classList.add("table", "table-striped", "table-bordered");
var thead = document.createElement('thead');
thead.classList.add("cal-thead");
tbe.appendChild(thead);
var tre = document.createElement('tr');
for (var i = 0; i < columns.length; i++) {
var the = document.createElement('th');
the.classList.add("cal-toprow");
the.textContent = columns[i];
tre.appendChild(the);
}
thead.appendChild(tre);
var tbody = document.createElement('tbody');
tbody.classList.add("cal-tbody");
tbe.appendChild(tbody);
var week = 0;
//tbody.appendChild(CreateWeakHeader("Week " + week));
var tre = document.createElement('tr');
for (var j = 0; j < data.length; j++) {
if (j % 7 == 0) {
week++;
tbody.appendChild(CreateWeakHeader("Week " + week));
}
var thead = document.createElement('td');
thead.classList.add("ui-droppable");
thead.appendChild(data[j]);
tre.appendChild(thead);
tbody.appendChild(tre);
}
header3.appendChild(tbe);
document.body.appendChild(header);
}
$("#tb").click(function() {
var header = document.createElement("div");
header.innerHTML = "test";
var d = [header, header, header, header, header, header, header, header];
htmlTable(d, days);
});
var days = ['Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag'];
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="tb">CreateTable</button>
I'm trying to order the data that I get from my server to match the columns of my table.
My table columns are days from Monday to Sunday. When my data has more than 7items it needs to separate with another td. The td shows me week 1 and when my data has more than 7 items it needs to separate again that shows week 2 etc.
Update
Im now using a snipped verdion of my code.
Hope someone can help me out with this.
Thank you
There's a few things going on in the code that are problematic.
An attempt to add the table cells to the row, and the row to the table, was made on each iteration of the for loop. That would have produced a lot of rows with single cells had it worked.
It didn't work because there was only ever a single instance of tre, the row variable. So that meant the line tbody.appendChild(tre); did nothing, since appendChild won't append an element that already has a parent element.
Because your data was an array of references to HTMLElements with parents, appending them using appendChild did nothing for the same reason.
I've amended the code below to take care of all of these situations.
Firstly, the code will append a clone of the data to the cell if it's an HTMLElement. I expect in your real code you won't need this, but for this example, why not? It then appends the cell to the row and continues to the next data element.
Secondly, when the data iterator is at 7, before it appends the "Week N" header, it appends a clone of the row, if it has cells on it.
Finally, after appending the clone of the row, the code will reset the row variable to a new instance of a tr element, with no cells.
I also made some variable name and formatting changes to your code just so I could more easily work with it.
function CreateWeakHeader(name) {
var tr = document.createElement('tr');
var td = document.createElement('td');
td.classList.add("cal-usersheader");
td.style.color = "#000";
td.style.backgroundColor = "#7FFF00";
td.style.padding = "0px";
td.appendChild(document.createTextNode(name));
tr.appendChild(td);
var thh = document.createElement('td');
thh.colSpan = "6"; // "31"; Why 31? A week has 7 days...
thh.style.color = "#FFFFFF";
thh.style.backgroundColor = "#7FFF00";
tr.appendChild(thh);
return tr;
}
function htmlTable(data, columns) {
var header = document.createElement("div");
header.classList.add("table-responsive");
var header2 = document.createElement("div");
header2.id = "calplaceholder";
header.appendChild(header2);
var header3 = document.createElement("div");
header3.classList.add("cal-sectionDiv");
header2.appendChild(header3);
if ((!columns) || columns.length == 0) {
columns = Object.keys(data[0]);
}
var tbe = document.createElement('table');
tbe.classList.add("table", "table-striped", "table-bordered");
var thead = document.createElement('thead');
thead.classList.add("cal-thead");
tbe.appendChild(thead);
var tre = document.createElement('tr');
for (var i = 0; i < columns.length; i++) {
var the = document.createElement('th');
the.classList.add("cal-toprow");
the.textContent = columns[i];
tre.appendChild(the);
}
thead.appendChild(tre);
var tbody = document.createElement('tbody');
tbody.classList.add("cal-tbody");
tbe.appendChild(tbody);
var week = 0;
//tbody.appendChild(CreateWeakHeader("Week " + week));
var tre = document.createElement('tr');
for (var j = 0; j < data.length; j++) {
if (j % 7 == 0) {
week++;
/* Major changes start here */
// if the row has cells
if (tre.querySelectorAll('td').length) {
// clone and append to tbody
tbody.appendChild(tre.cloneNode(true));
// reset table row variable
tre = document.createElement('tr');
}
// then append the Week header
tbody.appendChild(CreateWeakHeader("Week " + week));
}
var td = document.createElement('td');
td.classList.add("ui-droppable");
// Set the value of the cell to a clone of the data, if it's an HTMLElement
// Otherwise, make it a text node.
var value = data[j] instanceof HTMLElement ?
data[j].cloneNode(true) :
document.createTextNode(data[j]);
td.appendChild(value);
tre.appendChild(td);
}
// If the number of data elements is not evenly divisible by 7,
// the remainder will be on the row variable, but not appended
// to the tbody, so do that.
if (tre.querySelectorAll('td').length) {
tbody.appendChild(tre.cloneNode(true));
}
header3.appendChild(tbe);
document.body.appendChild(header);
}
$("#tb").click(function() {
var header = document.createElement("div");
header.innerHTML = "test";
var d = [header, header, header, header, header, header, header, header];
htmlTable(d, days);
});
var days = ['Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag'];
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.0/dist/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="tb">CreateTable</button>
I've been attempting to fetch user input value from input fields to later on set it into a summary table that creates cells using javascript but can't seem to get it to work.
Following is my code:
function summonTable(f) {
var sLoc = f.countryf.value();
var eLoc = f.countryt.value();
var sDate = f.sdate.value();
var eDate = f.edate.value();
var div = document.getElementById("summary");
var magicTable = document.getElementById('summaryTable').querySelectorAll('tbody tr'),
var row = document.createElement('tr');
var th = document.createElement('th');
th.textContent = sDate;
var td = document.createElement('td');
td.textContent = sLoc;
//To state which row and column this cell goes to.
row.appendChild(th);
div.appendChild(magicTable);
});
The function summonTable will take in the arguement form f that contains the input fields, I've tried basic textboxes, checkboxes, radios, but all to no avail. The variables sLoc, eLoc are basically texts for countries and sDate, eDate are supposed to be dates.
function summonTable(f) {
var sLoc = f.countryf.value();
var eLoc = f.countryt.value();
var sDate = f.sdate.value();
var eDate = f.edate.value();
var div = document.getElementById("summary");
// to get the last row of the table
var magicTable = document.getElementById('summaryTable').querySelectorAll('tbody tr:last-child'),
var row = document.createElement('tr');
var th = document.createElement('th');
th.textContent = sDate;
var td = document.createElement('td');
td.textContent = sLoc;
//To state which row and column this cell goes to.
row.appendChild(th);
magicTable.after(row); //To add the row after the last row
div.appendChild(magicTable);
});
Let me start by saying, I have seen very similar questions and yes; I have read through and tried to implement the suggested solutions. I am trying to have it so that only one checkbox in a row can be selected at a time. The most common answer I have seen is this one;
$('input.example').on('change', function() {
$('input.example').not(this).prop('checked', false);
});
This solution did work for me, but that was before I was creating my table dynamically. Here is my code currently. It is pulling the table data from a MySQL table via a JSON $.post.
function load() {
$.post(
"Returnsmedb.php",
function(response) {
var block = []
index = 0;
for (var item in response) {
var objectItem = response[item];
var firstname = objectItem.fname;
var lastname = objectItem.lname;
var username = objectItem.uname;
var email = objectItem.email;
var password = objectItem.password;
var deny = document.createElement("input");
deny.type = "checkbox";
deny.className = "chk";
deny.name = "deny";
deny.id = "deny";
var approve = document.createElement("input");
approve.type = "checkbox";
approve.className = "chk";
approve.name = "approve";
var moreinfo = document.createElement("input");
moreinfo.type = "checkbox";
moreinfo.className = "chk";
moreinfo.name = "moreinfo";
block.push(firstname);
block.push(lastname);
block.push(username);
block.push(email);
block.push(password);
block.push(deny);
block.push(approve);
block.push(moreinfo);
dataset.push(block);
block = [];
}
var data = [" First Name", " Last Name ", " User Name ", " Email ", "Password", " Deny", "Approve", "More Information"]
tablearea = document.getElementById('usersTable');
table = document.createElement('table');
thead = document.createElement('thead');
tr = document.createElement('tr');
for (var i = 0; i < data.length; i++) {
var headerTxt = document.createTextNode(data[i]);
th = document.createElement('th');
th.appendChild(headerTxt);
tr.appendChild(th);
thead.appendChild(tr);
}
table.appendChild(thead);
for (var i = 0; i < dataset.length; i++) {
tr = document.createElement('tr');
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td'));
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.appendChild(document.createElement('td')); //Added for checkbox
tr.cells[0].appendChild(document.createTextNode(dataset[i][0]));
tr.cells[1].appendChild(document.createTextNode(dataset[i][1]));
tr.cells[2].appendChild(document.createTextNode(dataset[i][2]));
tr.cells[3].appendChild(document.createTextNode(dataset[i][3]));
tr.cells[4].appendChild(document.createTextNode(dataset[i][4]));
tr.cells[5].appendChild((dataset[i][5])); //
tr.cells[6].appendChild((dataset[i][6])); //
tr.cells[7].appendChild((dataset[i][7])); //
table.appendChild(tr);
}
tablearea.appendChild(table);
}, 'json'
);
}
I have tried pasting the common solution in various areas but I still cannot get it to work. Any help would be greatly appreciated.
Thanks!
Please try this code
$('input.chk').on('change', function() {
if($('this:checked'))
{
var tr =$(this).parents('tr');
tr.find("input.chk").not(this).each(function(){
$(this).prop('checked', false);
});
}
});
I am building a table dynamically with JavaScript, and I need to nest another table which will be a jQuery datatable inside the first table which is HTML.
I have what I thought would work and after researching, I don't see why it isn't working. I am defining my first table, building out the header and then adding rows. Inside of a cell, I build the table that will be the datatable.
Using console.log, it looks to be built correctly, but it doesn't display correctly. Instead, it shows only the first table and then appears as if it is not in a table, but rather just haphazardly placed on the page. Here is my code. I would greatly appreciate it if someone will look at it and see if they see a problem with it.
By the way, I don't think it would make any difference, but my openDetailRow function is based on a click coming from a row in an existing datatable.
function openDetailRow() {
$("#gridTbl tr td:nth-child(1)").on("click",
function () {
var ndx = $(this).closest('tr').find('td:eq(0)').text();
var dataRow = reportApp.grid.fnGetData(this.parentNode);
addElements(dataRow);
});
}
function getDetails() {
$("#hdrTbl").dialog({
resizable: false,
modal: true,
title: "Order Details",
height: 250,
width: 700,
buttons: {
"Close": function () {
$(this).dialog('destroy');
$(this).remove();
$("#ordDiv").remove();
}
}
});
}
function buildHdrTable(dataRow){
var hdrDets = [];
hdrDets[0] = dataRow.ordnbr;
hdrDets[1] = dataRow.custordnbr;
hdrDets[2] = dataRow.carrier;
hdrDets[3] = dataRow.custid;
var rowDets = [];
dataRow.detail.forEach(
function (el) {
var rowAr = [];
rowAr[0] = el.invtid;
rowAr[1] = el.descr;
rowAr[2] = el.pcs;
rowAr[3] = el.status;
rowDets.push(rowAr);
});
hdrTbl = document.createElement('table');
hdrTbl.cellPadding = 5;
hdrTbl.style.width = '750px';
hdrTbl.style.display = 'none';
hdrTbl.setAttribute("id", "hdrTbl");
var hdrVals = ["Ord #", "Cust Ord #", "Ship Via", "Cust ID" ];
var tblHead = document.createElement('thead');
hdrTbl.appendChild(tblHead);
tblHeadRow = document.createElement("tr");
tblHead.appendChild(tblHeadRow);
for(var i =0; i < hdrVals.length; i++){
tblHeadRow.appendChild(document.createElement("th")).
appendChild(document.createTextNode(hdrVals[i]));
}
var hdrBody = document.createElement("tbody");
hdrTbl.appendChild(hdrBody);
var tr = hdrBody.insertRow();
var td1 = tr.insertCell();
var td2 = tr.insertCell();
var td3 = tr.insertCell();
var td4 = tr.insertCell();
td1.appendChild(document.createTextNode(hdrDets[0]));
td2.appendChild(document.createTextNode(hdrDets[1]));
td3.appendChild(document.createTextNode(hdrDets[2]));
td4.appendChild(document.createTextNode(hdrDets[3]));
var bdy = hdrBody.insertRow();
var bdyTbl = bdy.insertCell();
tbl = document.createElement('table');
tbl.style.width = '100%';
tbl.style.display = 'none';
//tbl.style.border = "1px solid black";
tbl.setAttribute("id", "ordertable");
var headVals = ["Inventory Number", "Description", "Number of Pieces", "Status"];
var thead = document.createElement('thead');
tbl.appendChild(thead);
var theadRow = document.createElement("tr");
thead.appendChild(theadRow);
for (var i = 0; i < headVals.length; i++) {
theadRow.appendChild(document.createElement("th"))
.appendChild(document.createTextNode(headVals[i]));
}
var tbody = document.createElement("tbody");
tbl.appendChild(tbody);
for (var i = 0; i < rowDets.length; i++) {
var tr = tbody.insertRow();
var td1 = tr.insertCell();
var td2 = tr.insertCell();
var td3 = tr.insertCell();
var td4 = tr.insertCell();
td1.appendChild(document.createTextNode(rowDets[i][0]));
td2.appendChild(document.createTextNode(rowDets[i][1]));
td3.appendChild(document.createTextNode(rowDets[i][2]));
td4.appendChild(document.createTextNode(rowDets[i][3]));
bdyTbl.appendChild(tbl);
}
return hdrTbl;
}
function addElements(dataRow) {
var body = document.body;
var hdrTbl = buildHdrTable(dataRow);
ordDiv = document.createElement("div");
ordDiv.appendChild(hdrTbl);
ordDiv.setAttribute("id", "ordDiv");
body.appendChild(ordDiv);
$("#ordertable").css('display', 'none');
$("#ordertable").dataTable(tbl);
getDetails();
console.log(hdrTbl);
}
The issue was caused because I was using display:none. Now here is the thing.. If you don't use that particular style attribute, then the table will show up on the page. However, since it is nested inside my first table, and the first table has the display:none style attribute already applied to it, then by applying it to the second table, it would not allow that table to be shown on page.
As for the skewed look, I had not set a colspan. So now, it is working perfectly. I commented out the display none and added this one line of code...
bdyTbl.setAttribute("colspan", 4);
I am using JavaScript to loop through some data and build a number of tables and am using Bootstrap with the class table table-hover. This works absolutely fine on all tables except the very last table to be produced. The bottom table is always sqashed and the hover over doesn't work. The columns resize to the correct size but that's about it.
I can't work it out, both tables have the class declared:
No matter how many tables are made it always happens on the very last table. I should point out that I've tried everything I can think of including adding a dummy table within the loop and the last interation but then that makes two squashed tables then.
Update: http://jsfiddle.net/si828/1ksyces5/8/
Code:
$('#tableContainer').empty();
var div = document.getElementById('tableContainer');
for (var i = 0; i < data.length; i++)
{
div.innerHTML = div.innerHTML;
var para = document.createElement("p");
var logo = document.createElement("a");
logo.setAttribute('class', 'glyphicon glyphicon-user');
para.appendChild(logo);
var node = document.createTextNode(" " + data[i].userName + " (" + data[i].userID + ") " );
para.appendChild(node);
var aTag = document.createElement("a");
aTag.setAttribute('data-id-proxy' , data[i].userID);
aTag.setAttribute('class' , 'open-AddUserModal');
aTag.setAttribute('href' ,'#addUserModal');
var span = document.createElement("span");
span.setAttribute('class', 'glyphicon glyphicon-plus');
aTag.appendChild(span);
para.appendChild(node);
para.appendChild(aTag);
para.setAttribute('class', 'text-primary');
div.appendChild(para);
var table = document.createElement('table'), tr, td, row, cell;
table.setAttribute('class', 'table table-hover');
table.setAttribute('id', 'table' + data[i].userID);
table.setAttribute('border', '1');
var header = table.createTHead();
var row = header.insertRow(0);
var cell = row.insertCell(0);
cell.setAttribute('style' , 'width: 20%');
cell.style.backgroundColor = '#eee';
cell.style.fontWeight = 'bold';
cell.innerHTML = "SRM";
var cell = row.insertCell(1);
cell.setAttribute('style' , 'width: 13%');
cell.style.backgroundColor = '#eee';
cell.style.fontWeight = 'bold';
cell.innerHTML = "Target User";
var cell = row.insertCell(2);
cell.setAttribute('style' , 'width: 20%');
cell.style.backgroundColor = '#eee';
cell.style.fontWeight = 'bold';
cell.innerHTML = "Target User Name";
for (row = 0; row < data[i].targetUsers.length; row++)
{
tr = document.createElement('tr');
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = data[i].targetUsers[row].srm;
table.appendChild(tr);
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = data[i].targetUsers[row].targetUser;
td = document.createElement('td');
tr.appendChild(td);
td.innerHTML = data[i].targetUsers[row].targetUserName;
}
document.getElementById('tableContainer').appendChild(table);
}
Based on your JSFiddle, your div.innerHTML = div.innerHTML; on line 10 should be the last statement of your outer for loop (on line 76). Otherwise your table doesn't get a <tbody>, causing bootstrap to malfunction.
Here is the fixed one: http://jsfiddle.net/wsLzk5wq/
If it is only the last table you could add custom css for the last table element by using a child selector.
E.g
HTML:
<div class="parent-container">
<table>
.......
</table>
</div>
CSS:
.parent-container table:last-child {
padding: 10px !important;
.......
}