This JavaScript code makes tables responsive:
/* Credits:
https://gist.github.com/jpen365/f34bbff7d9db99f912e1e75193071718 */
var headertext = [];
var headers = document.querySelectorAll("thead");
var tablebody = document.querySelectorAll("tbody");
for (var i = 0; i < headers.length; i++) {
headertext[i]=[];
for (var j = 0, headrow; headrow = headers[i].rows[0].cells[j]; j++) {
var current = headrow;
headertext[i].push(current.textContent);
}
}
for (var h = 0, tbody; tbody = tablebody[h]; h++) {
for (var i = 0, row; row = tbody.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
col.setAttribute("data-th", headertext[h][j]);
}
}
}
My question is how to exclude tables using class all tables with this class is-style-stripes for example this table:
<table class="wp-block-table aligncenter is-style-stripes">
<tbody>
<tr>
<th>Company</th><td>Amazon</td>
</tr>
<tr>
<th>Company</th><td>Google</td>
</tr>
</tbody>
</table>
If you want to get all tables without class you can use
document.querySelectorAll("table:not(.is-style-stripes)")
You will get all tables without that class
If you want tables with this class just use
document.querySelectorAll("table.is-style-stripes")
Then you can search for it's tbody or thead like
table.querySelectorAll("tbody")
Related
I am trying to update a table once a button is clicked. I have created the table and the button with the following HTML code
<button type="button" onclick="calculateMatrixFact()">Calculate MF!</button>
<table id = "matrix_factorization">
<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>
</table>
While the function that I am calling on the onclick event, is the following:
function calculateMatrixFact(){
var cache = CacheValues();
// split the array in two single arrays one per each user and movie
var user_matrix = createGroups(cache.mu, 2);
var score_matrix = createGroups(cache.ms, 2);
// remove the string user_name and movie_name
for (let i = 0; i < user_matrix.length && i < score_matrix.length; i++) {
user_matrix[i].shift();
score_matrix[i].shift();
}
var dot_matrix = [];
// perform the dot product
for (let j = 0; j < user_matrix.length; j++) {
for (let k = 0; k < score_matrix.length; k++) {
//console.log(user_matrix[j])
//console.log(score_matrix[k])
var dot_product = math.multiply(user_matrix[j], score_matrix[k]);
dot_matrix.push(dot_product);
}
}
// create the matrix and push back the string (first column of the table)
var dot_prod_matrix = createGroups(dot_matrix, 2);
dot_prod_matrix[0].unshift("Anna");
dot_prod_matrix[1].unshift("Jonny");
// from array to HTML table
fetch = document.getElementById('matrix_factorization');
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
}
I think the problem is that I do not reset the table each time the button is clicked, is that right? How can I delete the old info and insert the new ones?
Here you can see the full code: https://jsfiddle.net/932ebu0v/7/
Because of this block in very last of your function:
fetch = document.getElementById('matrix_factorization');
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
The fetch will get the existing table that having rows and you just inserting new rows into it.
Then, you can just clear whole table, re-add the header and insert the row (the clear and re-instantiation of the header would be done in one line of code !!):
fetch = document.getElementById('matrix_factorization');
// Just use this line to clear whole table and put back the header row
fetch.innerHTML = `<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>`; // Put your whole <th> here.
// as for the rest, just let it be
for (var i = 0; i < dot_prod_matrix.length; i++) {
var newRow = fetch.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
A simple solution would be to keep the 1st row in the <thead> element, given that it functions as the table's header. The rest of the rows go inside the <tbody> element. Only the table body is reset each time the button is clicked.
// access tbody (thead remains unimpacted)
var mfTableBody = document.querySelector('#matrix_factorization tbody');
mfTableBody.innerHTML = ''; // clear tbody
for (var i = 0; i < dot_prod_matrix.length; i++) {
// insert tr inside tbody
var newRow = mfTableBody.insertRow(fetch.length);
for (var j = 0; j < dot_prod_matrix[i].length; j++) {
var cell = newRow.insertCell(j);
cell.innerHTML = dot_prod_matrix[i][j];
}
}
<table id="matrix_factorization">
<thead>
<tr>
<th>User</th>
<th>Movie One</th>
<th>Movie Two</th>
</tr>
</thead>
<tbody></tbody>
</table>
I have a problem. I need insert cell in a row. The content of cell is an element of an array. But is duplicate... Here my code:
function addFila() {
var iframe = document.getElementById('myFrame');
var table = iframe.contentDocument.getElementsByClassName("head_to_head h2h_home")[0];
var row = table.insertRow(1);
var fila = ["fecha", "liga", "equipolocal", "equipovisitante", "goleslocal", "golesvisitante"];
for (let i = 0; i < 6; i++) {
row.insertCell(i);
for (let x = 0; x <= fila.length; x++) {
row.insertCell(i).innerHTML = fila[i];
}
}
}
What is wrong?
row.insertCell() return new cell. If you want to create cell and use it you should save created cell in variable. You get duplicate because you call insertCell twice. I hope code below can help you
var table = document.querySelector(".table");
var row = table.insertRow(-1);
var fila = ["fecha", "liga", "equipolocal", "equipovisitante", "goleslocal", "golesvisitante"];
for (let i = 0; i < fila.length; i++) {
const insertedCell = row.insertCell(i);
insertedCell.textContent = fila[i];
}
table td {
border: 1px solid lime;
}
<table class="table">
<tbody>
<tr>
<td>cell_1_1</td>
<td>cell_1_2</td>
</tr>
<tr>
<td>cell_2_1</td>
<td>cell_2_2</td>
</tr>
</tbody>
</table>
I've tried looking at sources to learn a little on a method of creating rows and cells, however I'm surely getting something wrong, the output puts all the data into the header. and doesnt generate rows.
Javscript:
function addRepairData() {
// Select the Table
var tbl = document.getElementById('repairInnerTable');
var headerText = ["ID", "Status", "Assigned To"];
var cellText = ["1", "Full", "willy wonka"];
// Set number of rows
var rows = 10;
var columns = headerText.length;
// create table header
for (var h = 0; h < columns; h++) {
var th = document.createElement("TH");
var thText = document.createTextNode(headerText[h]);
th.appendChild(thText);
document.getElementById("tableHead").appendChild(th);
}
for (var r = 0; r < rows; r++) {
var tr = document.createElement("TR");
var rowid = "row" + r;
document.getElementById(rowid).appendChild(tr);
for (var c = 0; c < columns; c++)
{
var td = document.createElement("TD");
var tdText = document.createTextNode(cellText[c]);
th.appendChild(tdText);
}
}
HTML:
<div class="stTableContainer" id="repairsTable">
<table style="width: 100%; color:white;" id="repairInnerTable">
<tr id="tableHead">
</tr>
<tr id="row0"></tr>
<tr id="row1"></tr>
<tr id="row2"></tr>
<tr id="row3"></tr>
<tr id="row4"></tr>
<tr id="row5"></tr>
<tr id="row6"></tr>
<tr id="row7"></tr>
<tr id="row8"></tr>
<tr id="row9"></tr>
</table>
</div>
EDIT:
I might have a lot of unneeded fluff in the code, that's from my trial and error attempts.
There are a few corrections, see code.
function addRepairData() {
// Select the Table
var tbl = document.getElementById('repairInnerTable');
var headerText = ["ID", "Status", "Assigned To"];
var cellText = ["1", "Full", "willy wonka"];
// Set number of rows
var rows = 10;
var columns = headerText.length;
// create table header
for (var h=0; h<columns; h++) {
var th = document.createElement('th');
var thText = document.createTextNode(headerText[h]);
th.appendChild(thText);
document.getElementById('tableHead').appendChild(th);
}
for (var r=0; r<rows; r++) {
var rowid = 'row' + r;
var tr = document.getElementById('row' + r);
for (var c=0; c<columns; c++) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(cellText[c]));
tr.appendChild(td);
}
}
}
addRepairData();
td {
text-align: center;
}
<div class="stTableContainer" id="repairsTable">
<table style="width: 100%;" id="repairInnerTable">
<tr id="tableHead"></tr>
<tr id="row0"></tr>
<tr id="row1"></tr>
<tr id="row2"></tr>
<tr id="row3"></tr>
<tr id="row4"></tr>
<tr id="row5"></tr>
<tr id="row6"></tr>
<tr id="row7"></tr>
<tr id="row8"></tr>
<tr id="row9"></tr>
</table>
</div>
For each row create a td element and add to the tr.
For each header create a th and add to the first tr element.
Your table font is set to white makes the text not visible in a white background.
// Select the Table
var tbl = document.getElementById('repairInnerTable');
var trh = document.getElementById('tableHead');
var headerText = ["ID", "Status", "Assigned To"];
var cellText = ["1", "Full", "willy wonka"];
// Set number of rows
var rows = 10;
var columns = headerText.length;
// create table header
for (var h = 0; h < columns; h++) {
var th = document.createElement("th");
th.innerText = headerText[h];
trh.appendChild(th);
}
for (var r = 0; r < rows; r++) {
var tr = document.getElementById("row" + r);
for (var c = 0; c < columns; c++)
{
var td = document.createElement("td");
td.innerText = cellText[c];
tr.appendChild(td);
}
}
<div class="stTableContainer" id="repairsTable">
<table style="width: 100%;" id="repairInnerTable">
<tr id="tableHead">
</tr>
<tr id="row0"></tr>
<tr id="row1"></tr>
<tr id="row2"></tr>
<tr id="row3"></tr>
<tr id="row4"></tr>
<tr id="row5"></tr>
<tr id="row6"></tr>
<tr id="row7"></tr>
<tr id="row8"></tr>
<tr id="row9"></tr>
</table>
</div>
Few things:
You're trying to put a TR inside of a TR. Either create one or use the existing ones, but not both.
you've got th.appendChild in the body section...should be td, not th.
you have to append the td to the tr in the body section.
This should work:
addRepairData();
function addRepairData() {
// Select the Table
var tbl = document.getElementById('repairInnerTable');
var headerText = ["ID", "Status", "Assigned To"];
var cellText = ["1", "Full", "willy wonka"];
// Set number of rows
var rows = 10;
var columns = headerText.length;
var thead = document.getElementById("tableHead");
// create table header
for (var h = 0; h < columns; h++) {
var th = document.createElement("TH");
var thText = document.createTextNode(headerText[h]);
th.appendChild(thText);
thead.appendChild(th);
}
for (var r = 0; r < rows; r++) {
var tr = document.createElement("TR");
var rowid = "row" + r;
tbl.appendChild(tr);
for (var c = 0; c < columns; c++) {
var td = document.createElement("TD");
var tdText = document.createTextNode(cellText[c]);
td.appendChild(tdText);
tr.appendChild(td);
}
}
}
<div class="stTableContainer" id="repairsTable">
<table style="width: 100%;background:gray; color:white;" id="repairInnerTable">
<tr id="tableHead"></tr>
</table>
</div>
I have a table with 10 rows and data is
ABC XYZ 30% (ABC)
ABC MNO 91% (XYZ)
var table = document.getElementById("table2");
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
var data = col.innerText;
var data1 = data.split(" ");
if(data1[0] == "91%"){
row.cells[j].css( "color", "red" );
}
}
}
I want to add red color to the cells which are above 90%. How to do it.
I know in back-end we can do it but now I am using only html and CSS.
Slight variation in your code can make it works
var table = document.getElementById("table2");
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
var data = col.innerText;
// replace % symbol, parse and compare with number
if (+data.replace('%', '') > 90) {
// update style property of cell
col.style.color = "red";
}
}
}
<table id="table2">
<tr>
<td>ABC</td>
<td>XYZ</td>
<td>30%</td>
<td>(ABC)</td>
</tr>
<tr>
<td>ABC</td>
<td>MNO</td>
<td>91%</td>
<td>(XYZ)</td>
</tr>
</table>
If a single column contains the entire string then do something like this
var table = document.getElementById("table2");
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
// get the percentage value from string
var data = col.innerText.match(/(\d+(?:\.\d+)?)%/);
// check match found or not then parse and compare with number
if (data && +data[1] > 90) {
// update style property of cell
col.style.color = "red";
}
}
}
<table id="table2">
<tr>
<td>ABC XYZ 30% (ABC)</td>
</tr>
<tr>
<td>ABC MNO 91% (XYZ)</td>
</tr>
</table>
I am trying to sum a table column total.
Here is an example of only two column for test purposes. I want to calculate table column's item total using a javascript loop.
How to create the loop if we don't know how many rows and columns are inside in table? I hope you understand what I mean and also hope for your kindly suggestion.
<p><b>Student at Stanford University 2013-2014</b></p>
<table><tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr></table>
<table id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
<tr><th>Engineering</th><td>8750</td><td>9863</td></tr>
<tr><th>Humanities & Sciences</th><td>7819</td><td>7219</td></tr>
<tr><th>Medicine</th><td>5219</td><td>4200</td></tr>
</table>
<button onclick="Calculate()">Calculate</button>
<div id="Studentf" class="Studentf"></div>
<div id="Students" class="Students"></div>
<div id="Studentt" class="Studentt"></div>
and
var ftable = document.getElementById("sdtable");
var i= 0;
var sumFirst=0;
var sumSecond=0;
var sumTotal=0;
function Calculate(){
for (i=0;i<ftable.rows.length; i++){
sumFirst=sumFirst+parseInt(ftable.rows[i].cells[1].innerHTML);
sumSecond=sumSecond+parseInt(ftable.rows[i].cells[2].innerHTML);
}
sumTotal=sumFirst+sumSecond;
document.getElementById("Studentf").innerHTML +="<b>Student in 2013 = </b>" +sumFirst;
document.getElementById("Students").innerHTML +="<b>Student in 2014 = </b>" +sumSecond;
document.getElementById("Studentt").innerHTML +="<b>Total Student = </b>" +sumTotal;
}
The key here is that you need to use cells collection to get number of columns that can change when you add new years to the table. You will also have to dynamically create elements for summary information per year.
Here is an example:
var ftable = document.getElementById("sdtable");
var i = 0;
var sumFirst = 0;
var sumSecond = 0;
var sumTotal = 0;
function Calculate() {
var rows = ftable.tBodies[0].rows,
header = ftable.tHead.rows[0],
cells = ftable.tBodies[0].rows[0].cells,
years = [];
for (var i = 0; i < rows.length; i++) {
for (var j = 1; j < cells.length; j++) {
if (!years[j]) years[j] = 0;
years[j] += parseInt(rows[i].cells[j].innerHTML);
}
}
sumTotal = years.reduce(function(prev, curr) {
return prev + curr;
}, 0);
var sum = document.getElementById("sum");
sum.innerHTML = '';
for (var j = 1; j < cells.length; j++) {
console.log(header.cells[j])
sum.insertAdjacentHTML('afterbegin', '<p><b>' + header.cells[j].innerHTML + '</b> = ' + years[j] + '</p>');
}
sum.insertAdjacentHTML('beforeend', "<b>Total Student = </b>" + sumTotal);
}
Demo: http://jsfiddle.net/x2sscpxL/1/
The table should probably look more like:
<table>
<thead>
<tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr>
</thead>
<tbody id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
...
</tbody>
<tfoot>
<tr><th>Totals:</th><th></th><th></th></tr>
</table>
to split the header, body and footer into separate table sections. The function should then be like:
function calculate(){
// Get a reference to the tBody
var tBody = document.getElementById('sdtable');
if (!tBody) return;
var row, rows = tBody.rows;
var cell, cells;
var cellTotals = {};
// For each row in the body
for (i=0, iLen=rows.length; i<iLen; i++) {
row = rows[i];
cells = row.cells;
// Add the cells in each column, starting on the second column
// i.e. starting with cell index 1
for (var j=1, jLen=cells.length; j<jLen; j++) {
cell = cells[j];
if (j in cellTotals) {
cellTotals[j] += Number(cell.textContent || cell.innerText);
} else {
cellTotals[j] = Number(cell.innerHTML);
}
}
}
// Write the totals into the footer
var tFoot = tBody.parentNode.tFoot;
row = tFoot.rows[0];
for (var k=1; k<jLen; k++) {
row.cells[k].innerHTML = cellTotals[k];
}
}
Note that by convention, variables with a name starting with a capital letter are reserved for constructors (though constants usually are all caps).
Here is calculation of table witn n rows and n columns
Note: header cells wrapped in thead section
var ftable = document.getElementById("sdtable");
var tbody = ftable.getElementsByTagName("tbody")[0]
var columnsCount = ftable.rows[0].cells.length;
var sumTotal = [];
for(i=0; i<columnsCount;i++)
sumTotal.push(0); //here initialize with zero
function Calculate(){
for (i=0;i<tbody.rows.length; i++){
for (j=0; j<columnsCount; j++)
if (tbody.rows[i].cells[j] && tbody.rows[i].cells[j].innerHTML)
sumTotal[j] += parseInt(tbody.rows[i].cells[j].innerHTML);
}
return sumTotal;
}
sumTotal = Calculate();
tfootrow = ftable.tFoot.rows[0];
console.log(tfootrow)
for(i=0; i<sumTotal.length; i++){
tfootrow.insertCell(i).innerHTML = sumTotal[i];
}
<table id="sdtable">
<thead>
<tr>
<th>Business</th>
<th>Earth Sciences</th>
<th>Education</th>
<th>Engineering</th>
<th>Humanities & Sciences</th>
<th>Medicine</th>
</tr>
</thead>
<tbody>
<tr><td>12922</td><td>11420</td></tr>
<tr><td>4320</td><td>4611</td></tr>
<tr><td>14560</td><td>13490</td></tr>
<tr><td>8750</td><td>9863</td></tr>
<tr><td>7819</td><td>7219</td></tr>
<tr><td>5219</td><td>4200</td></tr>
<tr><td></td><td>1</td><td>2</td></tr>
</tbody>
<tfoot>
<tr></tr>
</tfoot>
</table>