table collapse (rows hide) not working Javascript - javascript

function tablecollapse()
{
var table = document.getElementById(tblbatting);
var rowCount = table.rows.length;
for(var i=4; i< rowCount; i++)
{
var row = table.rows[i];
row.display="none";
}
}
I have this code running onload() but the table's connect aren't hiding.
What is wrong with this code? or any other suggestions?

What Wayne said. He was a lot faster than me.
function tablecollapse(id) {
var table = document.getElementById(id);
var rows = table.rows;
for (var i = 4; i < rows.length; i++) {
rows[i].style.display = "none";
}
}
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<table id="foo">
<thead>
<td>Column</td>
<td>Column</td>
</thead>
<tr>
<td>one</td>
<td>one</td>
</tr>
<tr>
<td>two</td>
<td>two</td>
</tr>
<tr>
<td>three</td>
<td>three</td>
</tr>
<tr>
<td>four</td>
<td>four</td>
</tr>
<tr>
<td>five</td>
<td>five</td>
</tr>
</table>
<button onclick="tablecollapse('foo')">Collapse</button>

There are two errors in the code. First, you need to put quotes around the table element id in var table = document.getElementById(tblbatting);. So, this code becomes var table = document.getElementById("tblbatting");.
Second, to set the display style, you need to access the style property of the table row element. So row.display="none"; becomes row.style.display="none";.
var table = document.getElementById("tblbatting");
var rowCount = table.rows.length;
for(var i=4; i< rowCount; i++)
{
var row = table.rows[i];
row.style.display="none";
}
I am not sure if you have done it deliberately or not, but you should be aware that your code will not hide the first 4 rows of the table because you have used var i=4 to initialise your loop counter.

Related

Re-order table columns in HTML dynamically with Javascript

I've a table in HTML looks like this:
Subjects
n1
n2
n3
subject1
10
0
0
subject2
0
5
20
<table>
<thead>
<tr>
<th class="subject">Subjects</th>
<th>n1</th>
<th>n2</th>
<th>n3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="subject">subject1</th>
<td>10</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th class="subject">subject2</th>
<td>0</td>
<td>5</td>
<td>20</td>
</tr>
</tbody>
</table>
Is there any thought or approach with javascript I could re-order columns in a specific order let order = ['n2','n1','n3']:
Subjects
n2
n1
n3
subject1
0
10
0
subject2
5
0
20
I've solved by turning the table into 2-dimensional array and sort it and turn it back into table HTML:
function tableToArray(tbl, opt_cellValueGetter) {
opt_cellValueGetter = opt_cellValueGetter || function(td) {
return td.textContent || td.innerText;
};
var twoD = [];
for (var rowCount = tbl.rows.length, rowIndex = 0; rowIndex < rowCount; rowIndex++) {
twoD.push([]);
}
for (var rowIndex = 0, tr; rowIndex < rowCount; rowIndex++) {
var tr = tbl.rows[rowIndex];
for (var colIndex = 0, colCount = tr.cells.length, offset = 0; colIndex < colCount; colIndex++) {
var td = tr.cells[colIndex],
text = opt_cellValueGetter(td, colIndex, rowIndex, tbl);
while (twoD[rowIndex].hasOwnProperty(colIndex + offset)) {
offset++;
}
for (var i = 0, colSpan = parseInt(td.colSpan, 10) || 1; i < colSpan; i++) {
for (var j = 0, rowSpan = parseInt(td.rowSpan, 10) || 1; j < rowSpan; j++) {
twoD[rowIndex + j][colIndex + offset + i] = text;
}
}
}
}
return twoD;
}
let order = ['n2', 'n1', 'n3', "Subjects"];
const sort2dArrayColumsByFirstRow = (array) => {
if (!Array.isArray(array)) return [];
const sortedFirstRow = array[0]
.map((item, i) => ({
v: item,
i: i
}))
.sort((a, b) => {
return order.indexOf(a.v) - order.indexOf(b.v);
});
return array.map((row) => row.map((_, i) => row[sortedFirstRow[i].i]));
};
function arrayToTable(columnNames, dataArray) {
var myTable = document.createElement('table');
var y = document.createElement('tr');
myTable.appendChild(y);
for (var i = 0; i < columnNames.length; i++) {
var th = document.createElement('th'),
columns = document.createTextNode(columnNames[i]);
th.appendChild(columns);
y.appendChild(th);
}
for (var i = 0; i < dataArray.length; i++) {
var row = dataArray[i];
var y2 = document.createElement('tr');
for (var j = 0; j < row.length; j++) {
myTable.appendChild(y2);
var th2 = document.createElement('td');
var date2 = document.createTextNode(row[j]);
th2.appendChild(date2);
y2.appendChild(th2);
}
}
document.querySelector('#tableEl').innerHTML = myTable.innerHTML;
}
let arr = tableToArray(document.querySelector('#tableEl'))
console.log('before:', arr)
let arrOrdered = sort2dArrayColumsByFirstRow(arr);
console.log('after:', arrOrdered);
arrayToTable(arrOrdered[0], arrOrdered.slice(1))
<table id="tableEl">
<thead>
<tr>
<th class="subject">Subjects</th>
<th>n1</th>
<th>n2</th>
<th>n3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="subject">subject1</th>
<td>10</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th class="subject">subject2</th>
<td>0</td>
<td>5</td>
<td>20</td>
</tr>
</tbody>
</table>
This is a good DOM question.
Tables are modified by the TABLE API.
https://html.spec.whatwg.org/multipage/tables.html
The TABLE element has THEAD, TFOOT, and TBODY elements. Use of these elements provides structure for your javascript. (Good job so far).
<table id="s-table">
<thead>
<tr>
<th class="subject">Subjects</th>
<th>n1</th>
<th>n2</th>
<th>n3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="subject">subject1</th>
<td>10</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th class="subject">subject2</th>
<td>0</td>
<td>5</td>
<td>20</td>
</tr>
</tbody>
</table>
Next, you'll need some javascript.
You'll also find insertBefore, and possibly before, and after Element methods handy.
https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
Get the TBODY element.
For each row, reorder(cell[i], cell[j]).
Let's start with
function resortTBody(tBody) {
const rows = tBody.rows;
for(let i = 0; i < tBody.rows.length; i++) {
reorderRow(rows[i]);
}
}
function reorderRow(row) {
let cells = row.cells;
row.insertBefore(cells[2], cells[1]);
}
This code has a hard-coded swap of cells. To reorder the cells to match a specific order, you'll need to modify reorderRow:
reorderRow(row, newOrder);
The TH's can be similarly reordered.
Design Notes: It's a good idea to minimize scope of identifiers. That is, put them in scope only as broad as it can be maximally justified.
If reorderRow is only needed for resortTbody, it can be restricted to private access.
let resortTBody = function(tBody) {
function resortTBodyInner(tBody) {
const rows = tBody.rows;
for(let i = 0; i < tBody.rows.length; i++) {
reorderRow(rows[i]);
}
}
function reorderRow(row) {
let cells = row.cells;
row.insertBefore(cells[2], cells[1]);
}
resortTBodyInner(tBody);
resortTBody = resortTBodyInner;
};
It might be desirable to maintain the column headers but resort their contents. That would require a subtle change to the approach.
It might be desirable to reset the table to its original state. All of that can be done.
The following one-liner will reorganize the columns in the desired order:
document.querySelectorAll("#tableEl tr").forEach(tr=>[...tr.children].forEach((_,i,a)=>tr.append(a[[0,2,1,3][i]])));
<table id="tableEl">
<thead>
<tr>
<th class="subject">Subjects</th>
<th>n1</th>
<th>n2</th>
<th>n3</th>
</tr>
</thead>
<tbody>
<tr>
<th class="subject">subject1</th>
<td>10</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<th class="subject">subject2</th>
<td>0</td>
<td>5</td>
<td>20</td>
</tr>
</tbody>
</table>

Deleting Empty Rows/Nodes

I am trying to delete the empty rows in a table. I traversed to those empty rows. But I don't know how to delete that particular node. I tried to traverse to the parent node and delete, but somehow it seems to show error.
empr[e].removeChild(empr[e].rows[et]) I used this inside the for loop
function emptyrows() {
var count = 0;
var empr = document.getElementsByClassName("tide");
var emlen = document.getElementsByClassName("tide").length;
alert(emlen);
for (var e = 0; e < emlen; e++) {
var emtab = empr[e].rows.length;
for (var et = 0; et < emtab; et++) {
if (empr[e].rows[et].innerHTML == "") {
} else {
console.log("Nothing Empty");
}
}
}
}
<table>
<tbody>
<tr>
<td>1</td>
<td>Barry</td>
<td>
<table class="tide">
<tr>50</tr>
<tr>10</tr>
<tr>200</tr>
</table>
</td>
</tr>
<tr>
<td>2</td>
<td>Allen</td>
<td>
<table class="tide">
<tr>50</tr>
<tr></tr>
<tr></tr>
</table>
</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>
<table class="tide">
<tr>50</tr>
<tr>20</tr>
<tr></tr>
</table>
</td>
</tr>
</tbody>
</table>
Try the below code, however you need to correct your HTML to be semantic (include inside ). But the code below should give you the general idea on how to proceed:
function emptyrows() {
var tables = document.getElementsByClassName("tide");
for (var i = 0; i < tables.length; i++) {
for (var j = 0; j < tables[i].childNodes.length; j++) {
if (tables[i].childNodes[j].innerHTML === '') {
tables[i].removeChild(tables[i].childNodes[j]);
}
}
}
}
emptyrows();

Getting coordinates of table cells and comparing with different tables via Javascript

It's really easy to access to coordinates of table cells with this and this example ways. But when I'm trying to get cells and compare with another table's cell which is avaible on page, a problem occurs. Because I don't know how to compare them in same time. After many hours I tried to do this, unfortunately, still there is no luck.
In following classic tables list below, shows 2 different tables with different id numbers:
<table id="a1">
<tbody>
<tr>
<td>RED</td>
<td>GREEN</td>
<td>BLUE</td>
</tr>
<tr>
<td>YELLOW</td>
<td>PINK</td>
<td>samespothere</td>
</tr>
</tbody>
</table>
<hr>
<table id="a2">
<tbody>
<tr>
<td>BLACK</td>
<td>BROWN</td>
<td>WHITE</td>
</tr>
<tr>
<td>CYAN</td>
<td>GRAY</td>
<td>samespothereANDsomeextra</td>
</tr>
</tbody>
</table>
And also, I'm using modified version of this JS example to get location of cells. This modified version I did is not able to make compare operation. I've just edited for make it easier.
var cells = document.getElementsByTagName("td"); //For all table cells on page.
var i;
for(i = 0; i < cells.length; i++)
{
cells[i].onclick = vera;
}
function vera()
{
var cellIndex = this.cellIndex + 1;
var rowIndex = this.parentNode.rowIndex + 1;
var centra = cellIndex +","+ rowIndex; //This gives the coordinate of cell which you clicked on.
alert(centra);
}
Here is my question: I need to make a compare operation when I click on samespothere(Example text I wrote) table cell. Compare operation should be able with the same location of other table. Lets think like this: If second table cell(same location, different table) includes some of clicked cell's text(from first table), alert must show up and say "This clicked text in table id=1 cell:2row:2, matched in table id=2 cell:2row:2".
And here is the online code: http://jsfiddle.net/LujydnaL/
I think this is what you want:
function vera()
{
var cellIndex = this.cellIndex + 1;
var rowIndex = this.parentNode.rowIndex + 1;
var centra = cellIndex +","+ rowIndex; //This gives the coordinate of cell which you clicked on.
alert(centra);
// new code here
table2 = document.getElementById('a2');
rowInTable2 = table2.getElementsByTagName('tr')[rowIndex-1];
cellInTable2 = rowInTable2.getElementsByTagName('td')[cellIndex-1];
console.log(cellInTable2);
// do something with cellInTable2 now
}
window.onload = function () {
document.getElementsByTagName('table')[0].addEventListener('click', function(element) {
var rowIndex = element.target.parentElement.rowIndex;
var cellIndex = element.target.cellIndex;
var compare = document.getElementsByTagName('table')[1].rows[rowIndex].cells[cellIndex];
var myNodelist = document.querySelectorAll("td");
var i;
for (i = 0; i < myNodelist.length; i++) {
myNodelist[i].style.backgroundColor = "white";
}
compare.style.backgroundColor = "grey";
document.getElementById('alert1').innerHTML = ('CLICK => Row index = ' + rowIndex + ', Column index = ' + cellIndex);
document.getElementById('alert2').innerHTML = ('COMPARE = ' + compare.innerHTML)
}, false);
}
tr, th, td {
padding: 0.2rem;
border: 1px solid black
}
table:hover {
cursor: pointer;
}
<table>
<tbody>
<tr>
<td>a11</td>
<td>a12</td>
<td>a13</td>
</tr>
<tr>
<td>a21</td>
<td>a22</td>
<td>a23</td>
</tr>
</tbody>
</table>
<p id="alert1"></p>
<hr>
<table>
<tbody>
<tr>
<td>b11</td>
<td>b12</td>
<td>b13</td>
</tr>
<tr>
<td>b21</td>
<td>b22</td>
<td>b23</td>
</tr>
</tbody>
</table>
<p id="alert2"></p>

Stripe table JavaScript

I am trying to make a table which will display colours for odd and even table rows, not sure where I'm going wrong
HTML:
<table id="tableStyles" border="1">
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</table>
JS:
var isEven = function(someNumber) {
return (someNumber%2 == 0) ? true : false;
};
if isEven = true {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "blue";
}
} else {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "red";
}
}
I'd suggest:
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tr'), function (tr) {
tr.classList.add((tr.rowIndex%2 === 0 ? 'even' : 'odd'));
});
This presumes you have styles set, in CSS, for tr.odd and tr.even; also that you're using a relatively up-to-date browser; Internet Explorer 8+ for document.querySelectorAll(), and Internet Explorer 9+ for Array.prototype.forEach().
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tr'), function(tr) {
// rowIndex is the index of the current <tr> in the table element:
tr.classList.add((tr.rowIndex % 2 === 0 ? 'even' : 'odd'));
});
.even {
color: red;
}
.odd {
color: blue;
}
<table id="tableStyles" border="1">
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</table>
Alternatively, if you wanted to stripe only those elements selected (without reference to the rowIndex):
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tbody tr'), function(tr, collectionIndex) {
// collectionIndex (regardless of name, it's the second argument) is
// the index of the current array-element in the array/collection:
tr.classList.add((collectionIndex % 2 === 0 ? 'even' : 'odd'));
});
Array.prototype.forEach.call(document.querySelectorAll('#tableStyles tbody tr'), function(tr, collectionIndex) {
tr.classList.add((collectionIndex % 2 === 0 ? 'even' : 'odd'));
});
.even {
color: red;
}
.odd {
color: blue;
}
<table id="tableStyles" border="1">
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Even</td>
<td>Even</td>
<td>Even</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
<tr>
<td>Odd</td>
<td>Odd</td>
<td>Odd</td>
</tr>
</tbody>
</table>
From the code I can see that you are new to JS. So I think it is good to point out where you are going wrong, than fixing the whole thing for you.
//Here you are creating a function to return true or false using a function which
//already returning true or false.
var isEven = function(someNumber) {
return (someNumber%2 == 0) ? true : false;
};
//above can be reduced to this.
(someNumber%2==0); //will return true if even and false if odd.
// The syntax of if statement is wrong. It should be if (statement) { do stuff here...}
// Notice the difference between '=' and '=='. The first assigns value and the second checks if both sides are same.
// The isEven function should have an input to give either true or false.
// Finally you should first get the rows in the table as an array and loop through it and then do this if statement.
if isEven = true {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "blue";
}
} else {
var styletab = document.getElementsByTagName("tableStyles");
var cells = table.getElementsByTagName("td");
for (var i = 0; i < styletab.length; i++) {
styletab[i].style.fontSize = "12px";
styletab[i].style.color = "red";
}
}
// the above should be organised in the format below.
var table = ;//get the table here.
var rows = ;//get the rows in the table here.
for (i in rows) {
var row = rows[i]; //get the current row
var cells = ;//get cells from the current row
if(i%2==0) {
//set formatting for the cells here if the row number is even.
} else {
//set formatting for the cells here if the row number is odd.
}
}
Make sure you are absolutely sure of how the selectors (getElementById etc) work and what do they return so that you can use them correctly. for example getElementsByTagName searches based on the tag name ('div' 'table' etc) but getElementById searches by the id of the tags - 'tableStyles' in this case. Hope I pointed you in the right direction.
Final Correct answer provided by Balamurugan Soundarara
//Here we are searching for the document for element with the id 'tableStyles'. This returns only one DOM element.
var table = document.getElementById("tableStyles");
//Here we are searching the table element for all elements of the tag 'tbody'. This returns an array of elements. Here there is only one so we just use the first one (hence the [0] at the end)
var body = table.getElementsByTagName("tbody")[0];
//Here we are searching the body element for all elements of the tag 'tr'. This returns an array of row elements.
var rows = body.getElementsByTagName("tr");
//Here we are looping through the elements in the rows array.
for (var i=0 ; i<rows.length; i++) {
//Here we select the nth row in the array based on the loop index.
var row = rows[i];
//Here we are searching the row element for all elements of the tag 'td'. This returns an array of cells in the row.
var cells = row.getElementsByTagName("td");
//We are looping through all the cells in the array.
for(var j=0; j<cells.length; j++) {
//set the fontsize
cells[j].style.fontSize = "12px";
//check if the row is even. see how we dont need the isEven function. you can directly use the == function with the modulo operator.
if( i%2==0 ) {
//if it is even then the color is set to blue
cells[j].style.color = "blue";
} else {
//if it is even then the color is set to blue
cells[j].style.color = "red";
}
}
}
http://jsfiddle.net/ar5suz2g/4/

Click table row and get value of all cells

I don't know JQuery, so I'm hoping there is a way to do this in pure Javascript.
I need to click on a table row and get the value of each cell in that row. Here is the format of my table:
<table class='list'>
<tr>
<th class='tech'>OCB</th>
<th class='area'>Area</th>
<th class='name'>Name</th>
<th class='cell'>Cell #</th>
<th class='nick'>Nickname</th>
</tr>
<tr onclick="somefunction()">
<td>275</td>
<td>Layton Installation</td>
<td>Benjamin Lloyd</td>
<td>(801) 123-456</td>
<td>Ben</td>
</tr>
</table>
Is there anyway short of putting a unique ID to each cell?
There is no need to add ids or add multiple event handlers to the table. One click event is all that is needed. Also you should use thead and tbody for your tables to separate the heading from the content.
var table = document.getElementsByTagName("table")[0];
var tbody = table.getElementsByTagName("tbody")[0];
tbody.onclick = function (e) {
e = e || window.event;
var data = [];
var target = e.srcElement || e.target;
while (target && target.nodeName !== "TR") {
target = target.parentNode;
}
if (target) {
var cells = target.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
data.push(cells[i].innerHTML);
}
}
alert(data);
};
<table class='list'>
<thead>
<tr>
<th class='tech'>OCB</th>
<th class='area'>Area</th>
<th class='name'>Name</th>
<th class='cell'>Cell #</th>
<th class='nick'>Nickname</th>
</tr>
</thead>
<tbody>
<tr>
<td>275</td>
<td>Layton Installation</td>
<td>Benjamin Lloyd</td>
<td>(801) 123-456</td>
<td>Ben</td>
</tr>
</tbody>
</table>
Example:
http://jsfiddle.net/ZpCWD/
Check this fiddle link
HTML:
<table id="rowCtr" class='list'>
<thead>
<tr>
<th class='tech'>OCB</th>
<th class='area'>Area</th>
<th class='name'>Name</th>
<th class='cell'>Cell #</th>
<th class='nick'>Nickname</th>
</tr>
</thead>
<tbody>
<tr>
<td>275</td>
<td>Layton Installation</td>
<td>Benjamin Lloyd</td>
<td>(801) 123-456</td>
<td>Ben</td>
</tr>
</tbody>
</table>
JAVASCRIPT:
init();
function init(){
addRowHandlers('rowCtr');
}
function addRowHandlers(tableId) {
if(document.getElementById(tableId)!=null){
var table = document.getElementById(tableId);
var rows = table.getElementsByTagName('tr');
var ocb = '';
var area = '';
var name = '';
var cell = '';
var nick = '';
for ( var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].onclick = function() {
ocb = table.rows[this.i].cells[0].innerHTML;
area = table.rows[this.i].cells[1].innerHTML;
name = table.rows[this.i].cells[2].innerHTML;
cell = table.rows[this.i].cells[3].innerHTML;
nick = table.rows[this.i].cells[4].innerHTML;
alert('ocb: '+ocb+' area: '+area+' name: '+name+' cell: '+cell+' nick: '+nick);
};
}
}
}
var elements = document.getElementsByTagName('td');
for (var i =0; i < elements.length; i++) {
var cell_id = 'id' + i;
elements[i].setAttribute('id', cell_id);
}
Maybe put something like this in function your onclick links to from the tr?
$("tr").click(function () {
var rowItems = $(this).children('td').map(function () {
return this.innerHTML;
}).toArray();
});
This shows the row's first cell which is clicked according to dataTr.querySelectorAll("td")[0].innerText;
document.querySelector("#myTable").addEventListener("click",event => {
let dataTr = event.target.parentNode;
let dataRes = dataTr.querySelectorAll("td")[0].innerText;
console.log(dataRes);
});

Categories

Resources