Pure JS Create Table Dynamically - javascript

I am trying to create a table dynamically for many items as soon as a page loads. However, the table is not displayed on the page. So, I put my code (+100 lines) on https://jsfiddle.net/hbbz040/6qjguebd/7/.
What's wrong with the code? I have looked at other discussion threads on this topic, but none have helped.
Any help and/or changes to the code are welcome!
Here is the expected result for each of thousands items that could be loaded on page.
<section class="col-1-60">
<div class="a">
<h3 class="b"></h3>
<div class="c">
<div class="d">
<div class="c">
<table>
<tbody>
<tr class="dheader">
<th rowspan="2">A</th>
<th rowspan="2">B</th>
<th colspan="4">C</th>
<th colspan="3">D</th>
<th colspan="3">E</th>
</tr>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
<th>9</th>
<th>10</th>
</tr>
<tr>
<td>1</td>
<td class="d">
<figure class="e">
<a><img src="world1.png"></a>
<figcaption><a></a></figcaption>
</figure>
<figure class="e">
<a><img src="world2.png"></a>
<figcaption><a></a></figcaption>
</figure>
</td>
<td>2</td>
<td class="f">1</td>
<td class="g">1</td>
<td class="f g">3</td>
<td>4</td>
<td>4</td>
<td class="f g">$1.000</td>
<td>100%</td>
<td>100%</td>
<td class="f g">1.000</td>
</tr>
<tr>
<td>1</td>
<td class="d">
<figure class="e">
<a><img src="world3.png"></a>
<figcaption><a></a></figcaption>
</figure>
<figure class="e">
<a><img src="world4.png"></a>
<figcaption><a></a></figcaption>
</figure>
</td>
<td>2</td>
<td class="f">1</td>
<td class="g">1</td>
<td class="f g">3</td>
<td>4</td>
<td>4</td>
<td class="f g">1.000</td>
<td>100%</td>
<td>100%</td>
<td class="f g">1.000</td>
</tr>
<tr>
<td>1</td>
<td class="d">
<figure class="e">
<a><img src="world5.png"></a>
<figcaption><a></a></figcaption>
</figure>
<figure class="e">
<a><img src="world6.png"></a>
<figcaption><a></a></figcaption>
</figure>
</td>
<td>2</td>
<td class="f">1</td>
<td class="g">1</td>
<td class="f g">3</td>
<td>4</td>
<td>4</td>
<td class="f g">$1.000</td>
<td>100%</td>
<td>100%</td>
<td class="f g">1.000</td>
</tr>
<tr>
<td>1</td>
<td class="d">
<figure class="e">
<a><img src="world7.png"></a>
<figcaption><a></a></figcaption>
</figure>
<figure class="e">
<a><img src="world8.png"></a>
<figcaption><a></a></figcaption>
</figure>
</td>
<td>2</td>
<td class="f">1</td>
<td class="g">1</td>
<td class="f g">3</td>
<td>4</td>
<td>4</td>
<td class="f g">1.000</td>
<td>100%</td>
<td>100%</td>
<td class="f g">1.000</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>
Pure JS
function start() {
var arr0 = ["A", "B", "C", "D", "E"];
var arr1 = ['2', '2', '4', '3', '3'];
var arr2 = ["rowspan", "rowspan", "colspan", "colspan", "colspan"]
var arr3 = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var part = ["SD-001", "SD-002", "SD-003", "SD-004", "SD-005", "SD-006", "SD-007", "SD-008"];
var label = ["world1.png", "world2.png", "world3.png", "world4.png", "world5.png", "world6.png", "world7.png"];
var sec, idx, cab, tac0, tcs, tac1, th, td, a0, a1, img, mycurrent_row, currenttext, figure, figcaption;
var grid = document.getElementsByClassName('grid')[0];
var total_prod = 200;
for(var s = 0; s < total_prod; s++) {
sec = document.createElement('SECTION');
sec.setAttribute('class', 'col-1-60');
idx = document.createElement('DIV');
idx.setAttribute('class', 'a');
cab = document.createElement('H3');
cab.setAttribute('class', 'b');
tac0 = document.createElement('DIV');
tac0.setAttribute('class', 'c');
tcs = document.createElement('DIV');
tcs.setAttribute('class', 'd');
tac1 = document.createElement('DIV');
tac1.setAttribute('class', 'c');
var mytable = document.createElement("table");
var mytablebody = document.createElement("tbody");
for(var j = 0; j < 6; j++) {
mycurrent_row = document.createElement("tr");
if(j = 0) {
mycurrent_row.setAttribute('class', 'dheader');
for(var a = 0; a < arr0.lenght; a++) {
th = document.createElement('th');
th.setAttribute(arr2[a], arr1[a]);
currenttext = document.createTextNode(arr0[a]);
th.appendChild(currenttext);
mycurrent_row.appendChild(th);
mytablebody.appendChild(mycurrent_row);
}
} else if(j = 1) {
for(var b = 0; b < arr3.lenght; b++) {
th = document.createElement('th');
currenttext = document.createTextNode(arr3[b]);
th.appendChild(currenttext);
mycurrent_row.appendChild(th);
mytablebody.appendChild(mycurrent_row);
}
} else if(j > 1) {
for(var l = 0; l < 12; l++) {
td = document.createElement('td');
if(l = 0) {
td.appendChild(document.createTextNode(j + 1));
}
if(l = 1) {
td.setAttribute("class", "d");
for(var m = 0; m < 2; m++) {
figure = document.createElement('figure');
figure.setAttribute('class', 'e');
a0 = document.createElement('a');
img = document.createElement('img');
img.setAttribute('src', label[j + j + m]);
figcaption = document.createElement('figcaption');
a1 = document.createElement('a');
a1.appendChild(document.createTextNode(part[j + j + m]));
figcaption.appendChild(a1);
img.appendChild(figcaption);
a0.appendChild(img);
figure.appendChild(a0);
td.appendChild(figure);
}
}
if(j = 2) {
td.appendChild(document.createTextNode("2"));
}
if(j = 3) {
td.setAttribute('class', 'f');
td.appendChild(document.createTextNode("1"));
}
if(j = 4) {
td.setAttribute('class', 'g');
td.appendChild(document.createTextNode("1"));
}
if(j = 5) {
td.setAttribute('class', 'f g');
td.appendChild(document.createTextNode("3"));
}
if(j = 6) {
td.appendChild(document.createTextNode("4"));
}
if(j = 7) {
td.appendChild(document.createTextNode("4"));
}
if(j = 8) {
td.setAttribute('class', 'f g');
td.appendChild(document.createTextNode("1.000"));
}
if(j = 9) {
td.appendChild(document.createTextNode("200"));
}
if(j = 10) {
td.appendChild(document.createTextNode("206"));
}
if(j = 11) {
td.setAttribute('class', 'f g');
td.appendChild(document.createTextNode("0.971"));
}
mycurrent_row.appendChild(td);
mytablebody.appendChild(mycurrent_row);
}
mytablebody.appendChild(mycurrent_row);
}
}
mytable.appendChild(mytablebody);
tac1.appendChild(mytable);
tcs.appendChild(tac1);
tac0.appendChild(tcs);
cab.appendChild(tac0);
idx.appendChild(cab);
sec.appendChild(idx);
grid.appendChild(sec);
}
}

check this https://jsfiddle.net/6qjguebd/42/
in your code, conditions were wrongly checked
if(j = 0) {
should be
if(j == 0) { or if(j === 0) {
also, need to include the script in the head wrap

Related

Collapsing tables within tables

I am attempting to collapse a table when the onclick event occurs. I iterate through the rows of a table and either set their visibility to collapse or to visible. If there is a table in one of the table data elements, setting the visibility of the row to visible doesn't affect the visibility of the table within. I tried to make the center loop recursive and call it on any inner table nodes, but that doesn't fix it. How can I fix this issue?
main.html
<html>
<head>
<title>Hello World</title>
</head>
<body>
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>
<script>
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i=0; i<tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this,1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.getElementsByTagName("tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
} else {
rows[i].style.visibility = "collapse";
}
}
}
</script>
</body>
</html>
Great question. The issue is with this code:
var rows = tbl.getElementsByTagName("tr");
That retrieves all the table's TR elements, including those within sub-tables.
You want only the .collapsible table's rows. This is a little tricky, because tables automatically add TBODY elements if you haven't done so explicitly.
This gives the rows you need:
var rows = tbl.querySelectorAll(":scope > tbody > tr");
And you can get rid of this code:
tblss = rows[i].getElementsByTagName("table");
for (j=0; j < tblss.length; j++) {
collapseAlg(tblss[j],0);
}
Snippet:
var tbls = document.getElementsByClassName("collapsible");
var tblCnt = tbls.length;
init();
function init() {
var i;
for (i = 0; i < tblCnt; i++) {
tbls[i].addEventListener("click", collapse);
}
}
function collapse() {
collapseAlg(this, 1)
}
// start=0 -> collapse all rows, start=1 -> collapse all except the first row (assume no th)
function collapseAlg(tbl, start) {
console.log("called", tbl);
var rows = tbl.querySelectorAll(":scope > tbody > tr");
var i;
var j;
var datum;
for (i = start; i < rows.length; i++) {
if (window.getComputedStyle(rows[i]).visibility === "collapse") {
rows[i].style.visibility = "visible";
} else {
rows[i].style.visibility = "collapse";
}
}
}
<table class="collapsible" cellpadding="2" cellspacing="0" border="2" bgcolor="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 1</td>
<td style="word-wrap: break-word;">datum 2</td>
</tr>
<tr>
<td>
<table CELLPADDING="2" CELLSPACING="0" BORDER="2" BGCOLOR="lightgrey">
<tr>
<td style="word-wrap: break-word;">datum 3</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 4</td>
</tr>
</table>
</td>
</tr>
<tr>
<td style="word-wrap: break-word;">datum 5</td>
<td style="word-wrap: break-word;">datum 6</td>
</tr>
</table>

loop over table to set the background css

My HTML table has some classes and table tag is used
Want to retain the classes as is, but all my table and tr , th or td are using td bgcolor which is an old technique.
I want to loop over the table and find if that bgcolor is defined, use the same color and convert it to a css based background color so i can print it in IE
function setBackground() {
var table = document.getElementById("table1");
//i found this in a previous stack overflow answer and tried it
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
//this is for debugging purposes... I can't even get this to work
alert(table.rows[i].cells[j]);
table.rows[i].cells[j].style.background = "orange"; //just an example
}
}
}
because IE is not able to print the background lines and colors for some reason using the webkit property
I cleaned up the for loops a little. You can read the attribute with getAttribute and set the style.
var table = document.getElementById("table1");
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i]
for (var j = 0; j < row.cells.length; j++) {
var cell = row.cells[j]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
You can just do it with one loop with getElementsByTagName
var tds = document.getElementById("table1").getElementsByTagName("td");
for (var i = 0; i < tds.length; i++) {
var cell = tds[i]
var bgc = cell.getAttribute('bgcolor')
if (bgc) {
cell.style.background = bgc
}
}
td {
width: 30px; height: 30px;
}
<table id="table1">
<tr>
<td bgcolor="red"></td>
<td></td>
<td bgcolor="blue"></td>
</tr>
<tr>
<td></td>
<td bgcolor="green"></td>
<td></td>
</tr>
<tr>
<td bgcolor="yellow"></td>
<td></td>
<td></td>
</tr>
<tr>
<td bgcolor="silver"></td>
<td></td>
<td></td>
</tr>
</table>
Get the color if found and then do with it whatever needed...
function setBackgroundColor(colorValue) {
const table = document.getElementById("table1");
const rows = table.children[0].rows
for (let i = 0; i < rows.length; i++) {
const tds = rows[i].children;
for (let j = 0; j < tds.length; j++) {
if (tds[j].bgColor === colorValue) {
console.log('Color found, do action')
}
}
}
}
setBackgroundColor('red')
<table id="table1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td bgcolor="red">January</td>
<td bgcolor="green">$100</td>
</tr>
</table>
You can do this:
var cells = $("#targetTable td");
for(i in cells){
color = $(cells[i]).attr('bgcolor');
console.log(color);
$(cells[i]).css({background: color});
}
as Taplar mentioned in the comment :
Use document.querySelectorAll('td[bgcolor]') to get the td that have bgcolor, loop through them and set the background to that color :
document.querySelectorAll('td[bgcolor]').forEach(e => {
const bgColor = e.getAttribute('bgcolor');
e.removeAttribute('bgcolor'); // optional, if you want to remove the attribute
e.style.background = bgColor;
})
<table id="table1">
<thead>
<th>A</th>
<th>B</th>
<th>C</th>
</thead>
<tbody>
<tr>
<td bgcolor="red">1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td bgcolor="green">5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td bgcolor="blue">9</td>
</tr>
</tbody>
</table>

Delete a column

I have a table and I want to delete the column of a table. I have written a code to delete a particular column.
function deleteColumn(index) {
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
Now What should do so that I could select a particular column(header) and click on delete so that that particular column gets deleted?
You can refer this link for delete column http://www.mredkj.com/tutorials/tableaddcolumn.html
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
// 2006-08-21 - Created
// 2006-11-05 - Modified - head and body
function addColumn(tblId)
{
var tblHeadObj = document.getElementById(tblId).tHead;
for (var h=0; h<tblHeadObj.rows.length; h++) {
var newTH = document.createElement('th');
tblHeadObj.rows[h].appendChild(newTH);
newTH.innerHTML = '[th] row:' + h + ', cell: ' + (tblHeadObj.rows[h].cells.length - 1)
}
var tblBodyObj = document.getElementById(tblId).tBodies[0];
for (var i=0; i<tblBodyObj.rows.length; i++) {
var newCell = tblBodyObj.rows[i].insertCell(-1);
newCell.innerHTML = '[td] row:' + i + ', cell: ' + (tblBodyObj.rows[i].cells.length - 1)
}
}
function deleteColumn(tblId)
{
var allRows = document.getElementById(tblId).rows;
for (var i=0; i<allRows.length; i++) {
if (allRows[i].cells.length > 1) {
allRows[i].deleteCell(-1);
}
}
}
<form>
<p>
<input type="button" value="add column" onclick="addColumn('tblSample')" />
<input type="button" value="delete column" onclick="deleteColumn('tblSample')" />
</p>
<table id="tblSample" border="1">
<thead>
<tr>
<th>[th] row:0, cell: 0</th>
<th>[th] row:0, cell: 1</th>
<th>[th] row:0, cell: 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>[td] row:0, cell: 0</td>
<td>[td] row:0, cell: 1</td>
<td>[td] row:0, cell: 2</td>
</tr>
<tr>
<td>[td] row:1, cell: 0</td>
<td>[td] row:1, cell: 1</td>
<td>[td] row:1, cell: 2</td>
</tr>
<tr>
<td>[td] row:2, cell: 0</td>
<td>[td] row:2, cell: 1</td>
<td>[td] row:2, cell: 2</td>
</tr>
</tbody>
</table>
</form>
To delete a particular column, you can use the cellIndex of the element (see: TableData cellIndex Property)
function deleteColumn(element) {
var idx = element.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(idx);
}
}
}
<table id="testBenchTable">
<tr>
<th onclick="deleteColumn(this)">Month</th>
<th onclick="deleteColumn(this)">Savings</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</table>
function deleteColumn(event) {
var index = event.target.cellIndex;
var total_row = document.getElementById("testBenchTable").rows;
for (var i=0; i<total_row.length; i++) {
if (total_row[i].cells.length > 1) {
total_row[i].deleteCell(index);
}
}
}
<table style="width:100%" id="testBenchTable">
<tr>
<th onclick="deleteColumn(event)">Firstname</th>
<th onclick="deleteColumn(event)">Lastname</th>
<th onclick="deleteColumn(event)">Age</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>

Sorting HTML table with subitems with JS

I have the following table:
<table border="0" cellspacing="0" cellpadding="0" id="table1">
<tbody>
<tr>
<th onclick="sortTable(0, this); return false;" class="sort-up" order="-1">ColumnA</th>
<th style="width: 12em;" onclick="sortTable(1, this); return false;" class="sort-none">ColumnB</th>
<th style="width: 9em;" onclick="sortTable(2, this); return false;" class="sort-none">ColumnC</th>
<th style="width: 10em;" onclick="sortTable(3, this); return false;" class="sort-none">ColumnD</th>
<th style="width: 6em;">ColumnE</th>
</tr>
<tr id="tr217E9B6C" type="root" level="217E9B6C" depth="0">
<td class="evenListRow" id="nocenter">
<div class="tier1">Root A</div>
</td>
<td class="evenListRow">1</td>
<td class="evenListRow">2</td>
<td class="evenListRow">3</td>
<td class="evenListRow">4</a>
</td>
</tr>
<tr id="tr217E9B6C-6E781501" type="sub" level="217E9B6C-6E781501" depth="1">
<td class="oddListRow" id="nocenter">
<div class="tier2">Sub A</div>
</td>
<td class="oddListRow">5</td>
<td class="oddListRow">6</td>
<td class="oddListRow">7</td>
<td class="oddListRow">8</td>
</tr>
<tr id="tr217E9B6C-852AB6E5" type="sub" level="217E9B6C-852AB6E5" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub B</div>
</td>
<td class="evenListRow">9</td>
<td class="evenListRow">10</td>
<td class="evenListRow">11</td>
<td class="evenListRow">12</td>
</tr>
<tr id="tr2BE7EAFE" type="root" level="2BE7EAFE" depth="0">
<td class="evenListRow" id="nocenter">
<div class="tier1">Root B</div>
</td>
<td class="evenListRow">13</td>
<td class="evenListRow">14</td>
<td class="evenListRow">15</td>
<td class="evenListRow">16</td>
</tr>
<tr id="tr2BE7EAFE-49A04568" type="sub" level="2BE7EAFE-49A04568" depth="1">
<td class="oddListRow" id="nocenter">
<div class="tier2">Sub C</div>
</td>
<td class="oddListRow">17</td>
<td class="oddListRow">18</td>
<td class="oddListRow">19</td>
<td class="oddListRow">20</td>
</tr>
<tr id="tr2BE7EAFE-DAE218A5" type="sub" level="2BE7EAFE-DAE218A5" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub D</div>
</td>
<td class="evenListRow">21</td>
<td class="evenListRow">22</td>
<td class="evenListRow">23</td>
<td class="evenListRow">24</td>
</tr>
<tr id="tr4FFACE4A" type="root" level="4FFACE4A" depth="0">
<td class="oddListRow" id="nocenter">
<div class="tier1">Root C</div>
</td>
<td class="oddListRow">25</td>
<td class="oddListRow">26</td>
<td class="oddListRow">27</td>
<td class="oddListRow">28</td>
</tr>
<tr id="tr4FFACE4A-B9A443CA" type="sub" level="4FFACE4A-B9A443CA" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub E</div>
</td>
<td class="evenListRow">29</td>
<td class="evenListRow">30</td>
<td class="evenListRow">31</td>
<td class="evenListRow">32</td>
</tr>
</tbody>
</table>
And I want to sort it, first by the "root" then by the "sub" items, which would mean that Root A will always have its Sub A, Sub B under it (sorted as well, but under it)
I used the following code which works on only on the "sub items", I cannot get it to work by doing a "mix", i.e. top and sub (separately sorted)
function sortTable(column, thisrow) {
var order = thisrow.getAttribute('order');
if (!order) {
order = 1;
}
var tbl = document.getElementById("table1").tBodies[0];
if (!tbl) {
return;
}
if (previousSortColumn && previousSortColumn.innerHTML != thisrow.innerHTML) {
previousSortColumn.setAttribute('class', 'sort-none');
}
previousSortColumn = thisrow;
var store = [];
/* Build a store object that has every element in the table, we will use this to sort */
for(var rowpos=1, len=tbl.rows.length; rowpos<len; rowpos++) { // skip row #1 as it is the header
var row = tbl.rows[rowpos];
var i_textContent = row.cells[column].textContent;
while(i_textContent.indexOf(' ') != -1) { // remove spaces
i_textContent = i_textContent.replace(' ', '');
}
var sortnr = i_textContent;
var type = row.getAttribute('type');
var level = row.getAttribute('level');
var depth = row.getAttribute('depth');
store.push({sortnr: sortnr, row:row, storelength:store.length, type:type, level:level, depth:depth});
}
/* We sort first roots then the elements under it */
store.sort(function(x,y) {
var xtype = x['type'];
var ytype = y['type'];
var result;
if (xtype == 'root' && ytype == 'root')
{
result = x['sortnr'].localeCompare(y['sortnr']);
} else {
return 0;
}
if (order == 1) {
return result;
} else {
return -1 * result;
}
});
/* We sort the elements under it */
store.sort(function(x,y) {
var xtype = x['type'];
var ytype = y['type'];
var xlevel = x['level'];
var ylevel = y['level'];
if (xlevel.lastIndexOf('-') > 0) {
xlevel = xlevel.substring(0, xlevel.lastIndexOf('-'));
}
if (ylevel.lastIndexOf('-') > 0) {
ylevel = ylevel.substring(0, ylevel.lastIndexOf('-'));
}
if (xlevel != ylevel || xtype == 'root' || ytype == 'root')
{
return x['storelength'] - y['storelength']; // return order inside array
}
var result = x['sortnr'].localeCompare(y['sortnr']);
if (order == 1) {
return result;
} else {
return -1 * result;
}
});
for(var i=0; i < store.length; i++) {
tbl.appendChild(store[i]['row']);
}
store = null;
}
Update 1:
Clicking once on 'ColumnB' would not affect the table (a bit of a bad example on my part), as the information is already sorted in the correct order, however another click should sort everything in reverse order
So both the Roots would be in reverse other, Root C, Root B, Root A, as well their sub items, Sub D before Sub C, ...
<table border="0" cellspacing="0" cellpadding="0" id="table1">
<tbody>
<tr>
<th onclick="sortTable(0, this); return false;" class="sort-up" order="-1">ColumnA</th>
<th style="width: 12em;" onclick="sortTable(1, this); return false;" class="sort-none">ColumnB</th>
<th style="width: 9em;" onclick="sortTable(2, this); return false;" class="sort-none">ColumnC</th>
<th style="width: 10em;" onclick="sortTable(3, this); return false;" class="sort-none">ColumnD</th>
<th style="width: 6em;">ColumnE</th>
</tr>
<tr id="tr4FFACE4A" type="root" level="4FFACE4A" depth="0">
<td class="oddListRow" id="nocenter">
<div class="tier1">Root C</div>
</td>
<td class="oddListRow">25</td>
<td class="oddListRow">26</td>
<td class="oddListRow">27</td>
<td class="oddListRow">28</td>
</tr>
<tr id="tr4FFACE4A-B9A443CA" type="sub" level="4FFACE4A-B9A443CA" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub E</div>
</td>
<td class="evenListRow">29</td>
<td class="evenListRow">30</td>
<td class="evenListRow">31</td>
<td class="evenListRow">32</td>
</tr>
<tr id="tr2BE7EAFE" type="root" level="2BE7EAFE" depth="0">
<td class="evenListRow" id="nocenter">
<div class="tier1">Root B</div>
</td>
<td class="evenListRow">13</td>
<td class="evenListRow">14</td>
<td class="evenListRow">15</td>
<td class="evenListRow">16</td>
</tr>
<tr id="tr2BE7EAFE-DAE218A5" type="sub" level="2BE7EAFE-DAE218A5" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub D</div>
</td>
<td class="evenListRow">21</td>
<td class="evenListRow">22</td>
<td class="evenListRow">23</td>
<td class="evenListRow">24</td>
</tr>
<tr id="tr2BE7EAFE-49A04568" type="sub" level="2BE7EAFE-49A04568" depth="1">
<td class="oddListRow" id="nocenter">
<div class="tier2">Sub C</div>
</td>
<td class="oddListRow">17</td>
<td class="oddListRow">18</td>
<td class="oddListRow">19</td>
<td class="oddListRow">20</td>
</tr>
<tr id="tr217E9B6C" type="root" level="217E9B6C" depth="0">
<td class="evenListRow" id="nocenter">
<div class="tier1">Root A</div>
</td>
<td class="evenListRow">1</td>
<td class="evenListRow">2</td>
<td class="evenListRow">3</td>
<td class="evenListRow">4</a>
</td>
</tr>
<tr id="tr217E9B6C-852AB6E5" type="sub" level="217E9B6C-852AB6E5" depth="1">
<td class="evenListRow" id="nocenter">
<div class="tier2">Sub B</div>
</td>
<td class="evenListRow">9</td>
<td class="evenListRow">10</td>
<td class="evenListRow">11</td>
<td class="evenListRow">12</td>
</tr>
<tr id="tr217E9B6C-6E781501" type="sub" level="217E9B6C-6E781501" depth="1">
<td class="oddListRow" id="nocenter">
<div class="tier2">Sub A</div>
</td>
<td class="oddListRow">5</td>
<td class="oddListRow">6</td>
<td class="oddListRow">7</td>
<td class="oddListRow">8</td>
</tr>
</tbody>
</table>
I solved your problem. I did reorganize the code to make it a lot more readable. Most of the logic is what you provided, i just added small bits. And btw, you have duplicate id references on id="nocenter" in your html.
Here is a working jsfiddle of my solution. The HTML is exactly the one you provided , with errors and all and no listener on column E. This js fiddle version has some more subs on root A. You can play with it as you will (add extra data). Summary of the code comes after it in the answer.
Update - taken your new input data in the comments , i updated the jsfiddle it would seem i kept the root in place, and it jumped out of subset. It was a matter of changing 1 line in sorting the subs. The new fiddle.
var ASC = 1;
var DESC = -1;
var SORTNR_INDEX = 0;
var LOWER = 1;
var UPPER = 2;
var previousSortColumn ;
var order;
/* The original build store you provided */
var buildStore = function(column,tbl){
var store = [];
for (var rowpos = 1, len = tbl.rows.length; rowpos < len; rowpos++) { // skip row #1 as it is the header
var row = tbl.rows[rowpos];
var i_textContent = row.cells[column].textContent;
while (i_textContent.indexOf(' ') != -1) { // remove spaces
i_textContent = i_textContent.replace(' ', '');
}
var sortnr = i_textContent;
var type = row.getAttribute('type');
var level = row.getAttribute('level');
var depth = row.getAttribute('depth');
store.push({sortnr: sortnr, row: row, storelength: store.length, type: type, level: level, depth: depth});
}
return store;
}
// the order convention you offered
var triggerOrder = function(){
if (order==ASC){
order = DESC;
} else if (order==DESC || !order){
order = ASC;
}
}
// the code you provided
var getLevel = function(obj){
if (obj && obj.lastIndexOf('-') > 0) {
return obj.substring(0, obj.lastIndexOf('-'));
}
return obj;
}
function sortRoot(a,b){
var aSort = a[SORTNR_INDEX], bSort = b[SORTNR_INDEX];
return compareWithOrder(aSort,bSort);
};
var sortSubs = function(x,y){
var xtype = x['type'];
var ytype = y['type'];
if (xtype == 'root'){
return -1;
} else if (xtype == ytype) {
var xSort = x['sortnr'];
var ySort = y['sortnr'];
return compareWithOrder(xSort,ySort);
}
}
var compareWithOrder = function(x,y){
if (isNaN(parseInt(x))) {
return order * x.localeCompare(y);
} else {
x = parseInt(x);
y = parseInt(y);
if (x < y) {
return -1 * order;
} else if (x > y) {
return 1 * order;
} else {
return 0;
}
}
};
//assumes they are aligned by depth (i.e. will always have a root then subs). if not, an additional sort can be made beforehand
function getGroupsByLevel(store){
var group = [];
var groupIndex=0;
var lower =0, upper, sortNo;
if (store.length > 0) {
var x,y;
for (var i = 0; i < store.length; i++) {
x = store[i];
if (store[i+1]){
y = store[i+1]
} else{
y = {};
}
var xtype = x['type'];
var ytype = y['type'];
if (xtype=='root'){
sortNo = x['sortnr'];
}
var xlevel = getLevel(x['level']);
var ylevel = getLevel(y['level']);
if (xlevel != ylevel){
group[groupIndex] = [sortNo,lower,i];
lower=i+1;
groupIndex++;
}
}
}
return group;
};
function sortTable(column, thisrow) {
order = thisrow.getAttribute('order');
triggerOrder();
thisrow.setAttribute('order',order);
var tbl = document.getElementById("table1").tBodies[0];
if (!tbl) return;
/* Build a store object that has every element in the table, we will use this to sort */
var store = buildStore(column,tbl);
var groups = getGroupsByLevel(store);
groups.sort(sortRoot);
var newStore=[];
for (var i=0;i<groups.length;i++){
var group = groups[i];
var rootAndSubs = store.slice(group[LOWER],group[UPPER]+1);
rootAndSubs.sort(sortSubs);
newStore=newStore.concat(rootAndSubs);
}
//update table
for (var i = 0; i < newStore.length; i++) {
tbl.appendChild(newStore[i]['row']);
}
store = null;
order = null;
}
Basically it goes like this:
set +trigger the order
build the store just like you intended
get groups of roots and their subs
sort the groups and then sort the each of the subs for the group
update the view
This is the first approach i thought of.

After setInterval( ) on click function will not work...Variable no longer increments

The code works for the most part.
Whenever the interval is set to refresh the game card, the onclick functions no longer work and the variable no longer increments.
What am I missing here?
You Can comment out the line with the setInterval() to see the desired outcome. It should refresh every second keeping the variable score and incrementing whenever someone clicks on the images. Thanks!
// var btn = document.getElementById('btn');
//btn.addEventListener('click', UpdateTable);
// Set the max length and Width
var maxWidth = 4;
var maxLength = 6;
// Returns a random number
function CreateRandom() {
return Math.floor(Math.random() * 2 + 1);
}
//function to create an image
function CreateGopher() {
var randomNumber = CreateRandom();
var image = "Sup";
if (randomNumber == 1) {
image = "<img src='gopher.jpg' class='gopher' height='100' width='100'>";
} else if (randomNumber == 2) {
image = "<img src='lettuce.jpg' class='lettuce' height='100' width='100'>";
}
return image;
}
//create table
function UpdateTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
function newTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
//Use The function update table
UpdateTable();
setTimeout(function() {
alert("Your Score is " + score)
}, 15000);
setInterval(UpdateTable, 1000);
var score = 0;
$(".lettuce").click(function() {
//alert( "You Clicked on the lettuce" );
score -= 5;
document.getElementById("scoreOut").innerHTML = score;
});
$(".gopher").click(function() {
//alert( "You Clicked on the lettuce" );
score += 5;
document.getElementById("scoreOut").innerHTML = score;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<center>
<div id="container">
<div id="header">
<h1>Welcome</h1>
<div id="scoreOut"></div>
</div>
<div id="content">
<table id="gameCard">
<tbody>
<tr>
<td id="cell00"> </td>
<td id="cell01"> </td>
<td id="cell02"> </td>
<td id="cell03"> </td>
</tr>
<tr>
<td id="cell10"> </td>
<td id="cell11"> </td>
<td id="cell12"> </td>
<td id="cell13"> </td>
</tr>
<tr>
<td id="cell20"> </td>
<td id="cell21"> </td>
<td id="cell22"> </td>
<td id="cell23"> </td>
</tr>
<tr>
<td id="cell30"> </td>
<td id="cell31"> </td>
<td id="cell32"> </td>
<td id="cell33"> </td>
</tr>
<tr>
<td id="cell40"> </td>
<td id="cell41"> </td>
<td id="cell42"> </td>
<td id="cell43"> </td>
</tr>
<tr>
<td id="cell50"> </td>
<td id="cell51"> </td>
<td id="cell52"> </td>
<td id="cell53"> </td>
</tr>
</tbody>
</table>
</div>
</div>
<br>
//<input id="btn" type="button" value="Play The Game!!" />
</center>
Figured it out!
Needed to put my JQUERY on.click goodies in the actual main function, which I did not have in the first place, in with the other functions nested in it.
<!--
To change this template use Tools | Templates.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gopher Broke</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<style>
#gameCard td{
padding:0; margin:0;
}
#gameCard {
border-collapse: collapse;
cursor:url(finger2.png), pointer;
}
</style>
</head>
<body>
<center>
<div id="container">
<div id="header">
<h1>GOPHER BROKE</h1>
<center>You have 15 seconds to stop as many gophers as possible!</center>
<div id="scoreOut">Score:</div>
<FORM>
<INPUT TYPE="button" onClick="history.go(0)" VALUE="Refresh">
</FORM>
</div>
<div id="content">
<table id="gameCard">
<tbody>
<tr>
<td id="cell00"> </td>
<td id="cell01"> </td>
<td id="cell02"> </td>
<td id="cell03"> </td>
</tr>
<tr>
<td id="cell10"> </td>
<td id="cell11"> </td>
<td id="cell12"> </td>
<td id="cell13"> </td>
</tr>
<tr>
<td id="cell20"> </td>
<td id="cell21"> </td>
<td id="cell22"> </td>
<td id="cell23"> </td>
</tr>
<tr>
<td id="cell30"> </td>
<td id="cell31"> </td>
<td id="cell32"> </td>
<td id="cell33"> </td>
</tr>
<tr>
<td id="cell40"> </td>
<td id="cell41"> </td>
<td id="cell42"> </td>
<td id="cell43"> </td>
</tr>
<tr>
<td id="cell50"> </td>
<td id="cell51"> </td>
<td id="cell52"> </td>
<td id="cell53"> </td>
</tr>
</tbody>
</table>
</div>
</div>
<br>
<!--<input id="btn" type="button" value="Play The Game!!" />-->
</center>
<script>
var score = 0;
function game(){
// var btn = document.getElementById('btn');
//btn.addEventListener('click', UpdateTable);
// Set the max length and Width
var maxWidth = 4;
var maxLength = 6;
// Returns a random number
function CreateRandom() {
return Math.floor(Math.random() * 4 + 1);
}
//function to create an image
function CreateGopher() {
var randomNumber = CreateRandom();
var image = "Sup";
if(randomNumber == 1){
image = "<img src='gopher.jpg' class='gopher' height='50' width='50'>";
}
else if(randomNumber == 2){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
else if(randomNumber == 3){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
else if(randomNumber == 4){
image = "<img src='lettuce.jpg' class='lettuce' height='50' width='50'>";
}
return image;
}
//create table
function UpdateTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
function newTable() {
// Iterate over each cell and set a random number
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < maxWidth; j++) {
tmp = 'cell' + i + j;
document.getElementById(tmp).innerHTML = CreateGopher();
}
}
}
//Use The function update table
UpdateTable();
$( ".lettuce" ).click(function() {
//alert( "You Clicked on the lettuce" );
score -= 5;
document.getElementById("scoreOut").innerHTML = "<h1>Score :" + score;
});
$( ".gopher" ).click(function() {
//alert( "You Clicked on the lettuce" );
score += 5;
document.getElementById("scoreOut").innerHTML = "<h1>Score :" + score;
});
}
game();
setInterval(game, 1000);
setTimeout(function ()
{alert("Your Score is " + score)
window.location.href = "startGame.html";
}, 16000);
</script>
</body>
</html>

Categories

Resources