How to apply CSS to table cell depending on conditions - javascript

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>

Related

Vanilla javascript update a table if a button is clicked

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>

How to exclude certain HTML class from JS code

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")

Adding table rows and column dynamically with jQuery

I'm trying to add rows and columns to a table using user input values to determine the number of rows and columns dynamically using jQuery. Below is my code which actually adds rows and columns but not according to the user's inputs
function makeGrid() {
let numOfRow = 0; let numOfCol = 0;
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
}
makeGrid();
Assuming a user inputs numOfRow = 2 and numOfCol = 2, I should have a table like this
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
Problem is my code seems to be adding extra but I haven't been able to figure it out. This is the result of my code
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
How do I fix my code?
try changing your code from:
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
into this
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
var body = $('.grid-canvas');
for (var i = 1; i <= numOfRow; i++) {
let row = $('<tr></tr>');
for (col = 1; col <= numOfCol; col++) {
row.append('<td></td>');
}
body.append(row);
}
});
what i have done in the above code is created a separate object for the table's body and then once my rows are created with the columns, I append them back to the table object.
Pure javascript code is here
function f(x, y) {
var rows = x,
rowButtonNumber = y;
var table = document.getElementById("myTable");
table.innerHTML = "";
for (var i = 0; i < rows; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < rowButtonNumber; j++) {
var td = document.createElement("td");
var btn = document.createElement("button");
btn.innerHTML = "btn " + (i + 1);
btn.id = "btn-" + i;
btn.onclick = function() {
alert(this.innerHTML);
};
td.appendChild(btn);
tr.appendChild(td);
}
}
}
function go() {
var row = document.getElementById("row").value;
var col = document.getElementById("col").value;
f(row, col);
}
<html>
<head>
<style>
td {
width: 200px;
height: 200px;
}
button {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
Rows
<input id="row" type="number" placeholder="Rows" />
<br> Columns
<input id="col" type="number" placeholder="Columns" />
<button onclick="go()">Go</button>
<table id="myTable" cellspacing="50">
</table>
</body>
It does not seem you are using the row variable. I would suggest appending newly created td to row instead of $('tr').

How to get min and max number from selected rows of table?

This refers to my previous question.
How to highlight/color multiple rows on selection?
<table id="toppings" border="1" cellpadding="2">
<tr id="id1">
<td>3</td>
<td>row12</td>
<td>row13</td>
</tr>
<tr id="id2">
<td>12</td>
<td>row22</td>
<td>row23</td>
</tr>
<tr id="id3">
<td>15</td>
<td>row32</td>
<td>row33</td>
</tr>
<tr id="id4">
<td>22</td>
<td>row42</td>
<td>row43</td>
</tr>
<tr id="id5">
<td>23</td>
<td>row52</td>
<td>row53</td>
</tr>
<tr id="id6">
<td>55</td>
<td>row62</td>
<td>row63</td>
</tr>
</table>
Javascript Code:
//Get list of rows in the table
var table = document.getElementById("toppings");
var rows = table.getElementsByTagName("tr");
var selectedRow;
//Row callback; reset the previously selected row and select the new one
function SelectRow(row) {
if (selectedRow !== undefined) {
selectedRow.style.background = "#d8da3d";
}
selectedRow = row;
selectedRow.style.background = "white";
}
//Attach this callback to all rows
for (var i = 0; i < rows.length; i++) {
var idx = i;
rows[idx].addEventListener("click", function(){SelectRow(rows[idx])});
}
But this time I have added an event to table for row selection and trying to get min and max value from selected rows (first column). Like above table, if I select middle four rows, i should get min = 12 and max = 23. How can this be implemented?
You can have two functions. I show the getMinValueExample().
function getMinValueExample(rows){
var minValue = null;
for (var i = 0; i < rows.length; i++){
var firstTd = rows[i].getElementsByTagName('td')[0];
var currentValue = parseInt(firstTd.innerHTML);
if(minValue == null || minValue > currentValue)
minValue = currentValue;
}
return minValue;
}
(not test so can contain some type errors but you should get the idea)
So if you call this after you've declared rows it returns the min value.
And if you call this one you get the max value
function getMaxValueExample(rows){
var maxValue = null;
for (var i = 0; i < rows.length; i++){
var firstTd = rows[i].getElementsByTagName('td')[0];
var currentValue = parseInt(firstTd.innerHTML);
if(maxValue == null || maxValue < currentValue)
maxValue = currentValue;
}
return maxValue;
}

Javascript cell color according to math

I have an html table with numbers. For example:
Col1 Col2 Col3
5 3 1
1 2 1
10 3 2
And I want to use Javascript in order each cell has a specific color background according to the following math:
if one of the three columns (for each row) is greater than the sum of the other 2 columns
for example:
Col1 > Col2 + Col3 => bkg color: #000
Col2 > Col1 + Col3 => bkg color: #333
Col3 > Col1 + Col3 => bkg color: #666
Can I do it with Javascript? Can anyone help with the code?
Here's something for you (http://jsfiddle.net/AbnCz/3/). This doesn't scale that well as an algo, but works as per your requirements. If you end up adding more rows/cols, add the appropriate colors in the colors array.
> update: made a perf update to cache the sum as opposed to determining it through each cell traversal
HTML
<table id="dataTable">
<tr>
<td>20</td>
<td>50</td>
<td>70</td>
</tr>
<tr>
<td>40</td>
<td>2</td>
<td>7</td>
</tr>
<tr>
<td>5</td>
<td>2</td>
<td>60</td>
</tr>
</table>
Javascript
var colors = ["#000","#333","#666"];
var t = document.getElementById('dataTable');
var rows = t.getElementsByTagName('tr'), row, cells, tgtCell, rowSum, othersSum;
// let's go through the rows
for(var r=0; r<rows.length; r++){
row = rows[r];
cells = row.getElementsByTagName('td');
rowSum = 0;
// lets get the sum for the row.
// we'll subtract each cell from it to get the remaining sum.
for(var _c=0; _c<cells.length; _c++){
rowSum += parseInt(cells[_c].textContent,10);
}
// let's go through the cells
for(var c=0; c<cells.length; c++){
tgtCell = cells[c];
tgtVal = parseInt(tgtCell.textContent, 10);
othersSum = rowSum - tgtVal;
// if the target is greater than the remaining sum, style it
if(tgtVal > othersSum){
tgtCell.style.backgroundColor = colors[c % colors.length];
}
}
}
Try this :
HTML:
<table id="dataTable">
<tr>
<td>3</td>
<td>5</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>4</td>
</tr>
<tr>
<td>16</td>
<td>13</td>
<td>2</td>
</tr>
</table>
JAVASCRIPT :
var table = document.getElementById('dataTable'), activeCells
row = table.getElementsByTagName('tr'),
cell = table.getElementsByTagName('td');
var colorArray = new Array('red', 'blue', 'yellow');
//loop through all rows
for ( var i = 0; i < row.length; ++i) {
//get cells currently being read
activeCells = row[i].getElementsByTagName('td');
//prepare storage
var cellArray = new Array(),
newCellArray = new Array(),
cellElementArray = new Array(),
sum = 0;
//loop through active cells
for ( var x = 0; x < activeCells.length; ++x ) {
var currentCell = activeCells[x],
cellVal = parseInt( currentCell.innerHTML );
cellArray[x] = cellVal;
newCellArray[x] = cellVal;
cellElementArray[x] = currentCell;
}
//loop through Cell Array
for ( var y = 0; y < cellArray.length; ++y ) {
newCellArray.splice(y, 1);
for ( var z = 0; z < newCellArray.length; ++z ) {
sum += newCellArray[z];
}
newCellArray = [];
for ( var n = 0; n < cellArray.length; ++n ) {
newCellArray[n] = cellArray[n];
}
console.log( sum);
if ( cellArray[y] > sum ) {
console.log( 'in');
cellElementArray[y].style.backgroundColor = colorArray[y];
}
sum = 0;
}
}
An additional feature that I implemented is that this is dynamic. Try to increase the number of cells and it will still calculate.
And please change the colorArray according to your preference. It is by column ordered. something like var colorArray = new Array('#000','#333','#667');
jsfiddle demo: http://jsfiddle.net/aVqCU/
I haven't tested this code myself. But it should be something like this:
var table = document.getElementById("table"); //Replace "table" with the id of your table in the HTML
var table = document.getElementById("table"); //Replace "table" with the id of your table in the HTML
for (var i = 0, row; row = table.rows[i]; i++) //iterate through rows
{
var cell1 = row.cells[0];
var cell2 = row.cells[1];
var cell3 = row.cells[2];
if(parseFloat(cell1.innerHTML) > (parseFloat(cell2.innerHTML) + parseFloat(cell3.innerHTML)))
{
cell1.style.backgroundColor = "#000";
}
if(parseFloat(cell2.innerHTML) > parseFloat(cell3.innerHTML) + parseFloat(cell1.innerHTML))
{
cell2.style.backgroundColor = "#333";
}
if(parseFloat(cell3.innerHTML) > parseFloat(cell2.innerHTML) + parseFloat(cell1.innerHTML))
{
cell3.style.backgroundColor = "#666";
}
}
You may need to use parseInt or parseFloat on the row.cells to convert the text to a number.

Categories