I have multiple tables in my html. The tables have the columns with class "valuation" and valuation_all".
If one of the two cells in "valuation" contains FAIL, than the cell with "valuation_all" should change the text from "status" to "FAIL". Otherwise it should show PASS.
This works for one table, but I don't know how to get this for each table. I tried it with jQuery .each(".taglist") but its not working. I think I have to reset the variable count. For each table the variable should be resetted to zero and than start counting. Now the it keeps counting and does not change the status cell properly.
One of the tables: (other tables are identical just other ID)
<p>
<table id="results1" class="taglist">
<th>Name</th><th>result</th>
<tr>
<td class="valuation">FAIL</td><td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
</p>
jQuery:
$(document).ready(function() {
var count= 0;
$('table.taglist').each(
function() {
var count= $(".valuation:contains('FAIL')").length
if(count> 0) {
$(".taglist td:contains('status')").html("FAIL");
}else{
$(".taglist td:contains('status')").html("PASS");
}
});
});
Every help is appreciated!
You can use this to solve it.
$(document).ready(function() {
var count = 0;
$('table.taglist').each(
function() {
var count = $(".valuation:contains('FAIL')",this).length
$("td:contains('status')", this).html(count > 0 ? "FAIL" : "PASS");
});
});
The main problem is that your selectors is not referring to the table your are "inside". By doing $(".valuation:contains('FAIL')",this) you tell the selector (".valuation:contains('FAIL')") to search for this inside your table
Demo
$(document).ready(function() {
var count = 0;
$('table.taglist').each(
function() {
var count = $(".valuation:contains('FAIL')",this).length
$("td:contains('status')", this).html(count > 0 ? "FAIL" : "PASS");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="results1" class="taglist">
<th>Name</th>
<th>result</th>
<tr>
<td class="valuation">FAIL</td>
<td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
<table id="results2" class="taglist">
<th>Name</th>
<th>result</th>
<tr>
<td class="valuation">PASS</td>
<td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
$(document).ready(function() {
$('table.taglist').each(function() {
let count= $(this).find(".valuation:contains('FAIL')").length;
$(this).find("td:contains('status')").html(count> 0 ? "FAIL" : "PASS");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="results1" class="taglist">
<th>Name</th><th>result</th>
<tr>
<td class="valuation">FAIL</td><td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
<table id="results2" class="taglist">
<th>Name</th><th>result</th>
<tr>
<td class="valuation">PASS</td><td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">PASS</td>
</tr>
</table>
<table id="results3" class="taglist">
<th>Name</th><th>result</th>
<tr>
<td class="valuation">FAIL</td><td class="valuation_all" rowspan=2>status</td>
</tr>
<tr>
<td class="valuation">FAIL</td>
</tr>
</table>
Related
There is a table:
<table style="width:920px;" id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1"><p style="font-style:italic;">Nazwa produktu</p></td>
<td class="cell1 style1"><p style="font-style:italic;">Waga [g]</p></td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20</td>
</tr>
<tr>
<td>raspberry</td>
<td>35</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="cell0 style1"><p style="font-weight:bold;">TOTAL</p></td>
<td class="cell1 style1"><p style="font-weight:bold;"></p></td>
</tr>
</tfoot>
</table>
How can I sum up all cells in tbody second column and put the result in tfoot cell also second column?
The table is dynamic. I would like to use jquery.
This would be one way of doing it:
let sum=$("#tblPotrawySkladniki tbody td:nth-child(2)").get().reduce((a,c)=>
+$(c).text().replace(",",".")+a,0);
$("#tblPotrawySkladniki tfoot td:nth-child(2)").text(sum);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<table id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1"><p style="font-style:italic;">Nazwa produktu</p></td>
<td class="cell1 style1"><p style="font-style:italic;">Waga [g]</p></td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20,3</td>
</tr>
<tr>
<td>raspberry</td>
<td>35,5</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="cell0 style1"><p style="font-weight:bold;">TOTAL</p></td>
<td class="cell1 style1"><p style="font-weight:bold;"></p></td>
</tr>
</tfoot>
</table>
Instead of parseInt() my script makes use of implicit type conversion with the unary + operator before $(c).text().
You can use jQuery .each() to cycle through the second td of each row, access the contents of the element using $(this).text(), then add them up as you go.
You should parse the value first so that they will add up as numbers and not concatenate.
let values = 0;
jQuery('table tbody tr td:nth-of-type(2)').each(function(){
let value = parseInt($(this).text(),10);
values += value;
});
console.log(values);
<table style="width:920px;" id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1">
<p style="font-style:italic;">Nazwa produktu</p>
</td>
<td class="cell1 style1">
<p style="font-style:italic;">Waga [g]</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td> 10</td>
</tr>
<tr>
<td>orange</td>
<td> <span class='price'>20</span></td>
</tr>
<tr>
<td>raspberry</td>
<td> <span class='price'>35</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" style="text-align:center"><span id="sum"></span></th>
</tr>
</tfoot>
$(document).ready(function() {
$('.price').each(function(i) {
calculateColumn(i);
});
});
function calculateColumn(index) {
var total = 0;
$('table tr').each(function() {
var value = parseInt($('.price', this).eq(index).text());
if (!isNaN(value)) {
total += value;
}
});
$('#sum').eq(index).text('Total: ' + total);
}
when I am inserting data into table it is automatically inserting one row in the bottom. How can I remove a extra blank row from the table
<table>
<tr>
<th>Name</th>
<th>Comment</th>
<th>Posted Date</th>
</tr>
<tr>
<td id ="result_name"></td>
<td id="result_comment"></td>
<td id="posteddate"></td>
</tr>
</table>
Add a style with visibility:collapse
<html>
<table border="1">
<tr>
<th>Name</th>
<th>Comment</th>
<th>Posted Date</th>
</tr>
<tr style="visibility:collapse">
<td id="result_name"></td>
<td id="result_comment"></td>
<td id="posteddate"></td>
</tr>
</table>
</html>
You can try to do it by using jquery:
$("td").each(function() {
if (this.innerText === '') {
this.closest('tr').remove();
}
});
This function will check all the "td" and remove them if they do not have any text inside.
You can use jQuery function to check the data is empty or not.
$("td").each(function() {
if (this.innerText === '') {
this.closest('tr').remove();
}
});
<table>
<tr>
<th>Name</th>
<th>Comment</th>
<th>Posted Date</th>
</tr>
<tr>
<td id ="result_name"></td>
<td id="result_comment"></td>
<td id="posteddate"></td>
</tr>
</table>
I have this table where I show in the td of white color is the consolidated information of the td of gray color.
Like this:
The yellow color fields "- Und" It should show the sum of the fields below.
The correct result would look something like this:
I have identified the tds by an id, but I can't get it to add up.
tdgray = gray
tdwhite = white
var total = 0;
$(".tdgray").each(function() {
total += parseInt($(this).text()) || 0;
});
$(".tdwhite").text(total);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<TABLE BORDER>
<TR>
<TD>price</TD>
</TR>
<TR>
<TD id="tdwhite" class="tdwhite"></TD>
</TR>
<TR>
<TD class="tdgray">421</TD>
</TR>
<TR>
<TD class="tdgray">124</TD>
</TR>
<TR>
<TD class="tdgray">982</TD>
</TR>
<TR>
<TD id="tdwhite" class="tdwhite">Und</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
</TABLE>
If you see the result works but adds all the gray tds and does not go from record to record, I have a table with more than 300 white tds, can be a problem some solution?
LOOK THE EXAMPLE HERE
Your explanation of what you are needing is quite confusing.
I believe this is what you are looking for. It uses nextUntil() to loop through the rows that have a tdgray after each tdwhite and sums that group
$(".tdwhite").text(function() {
var total = 0;
$(this).parent().nextUntil(':has(.tdwhite)').each(function() {
total += parseInt($(this).find('.tdgray').text()) || 0;
});
return total
});
.tdwhite{color:red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<TABLE BORDER>
<TR>
<TD>price</TD>
</TR>
<TR>
<TD id="tdwhite" class="tdwhite"></TD>
</TR>
<TR>
<TD class="tdgray">421</TD>
</TR>
<TR>
<TD class="tdgray">124</TD>
</TR>
<TR>
<TD class="tdgray">982</TD>
</TR>
<TR>
<TD class="tdwhite">Und</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
</TABLE>
Here is another (Vanilla JavaScript) solution:
document.querySelectorAll(".tdwhite").forEach(el => {
let p, total = 0;
for (p = el.parentNode.nextElementSibling;
(p && !p.querySelector('.tdwhite')); p = p.nextElementSibling)
total += +p.querySelector('.tdgray').textContent || 0;
el.textContent = total
});
.tdwhite {
color: red
}
<TABLE BORDER>
<TR>
<TD>price</TD>
</TR>
<TR>
<TD id="tdwhite" class="tdwhite">one</TD>
</TR>
<TR>
<TD class="tdgray">421</TD>
</TR>
<TR>
<TD class="tdgray">124</TD>
</TR>
<TR>
<TD class="tdgray">982</TD>
</TR>
<TR>
<TD class="tdwhite">Und</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
<TR>
<TD class="tdgray">200</TD>
</TR>
</TABLE>
I am having a difficult time in calculating in getting the percentage for a column in my html table for datatables.
In the table above, I have figured out how to get the sum of each column, but for "Column D" totals, I need to get the percentage which will be "(total of column B / total of column C) * 100. Also column F will be (total of column E / total of column A) instead of the sum which is shows now.
The total for column D is blank because the javascript code that I used, could not sum up column D because I am using a percent sign. So with my current code, I want to sum for column A,B,C,E,G and the percent for column D, and column F would be column E divide by column A.
How can I go about to calculate these totals using Datatables and javascript? Any help will be appreciated. Thank you.
$(document).ready(function() {
// DataTable initialisation
$('table.off-table1').DataTable({
"searching": false,
"info": false,
"paging": false,
"autoWidth": true,
"footerCallback": function ( row, data, start, end, display ) {
var api = this.api();
nb_cols = api.columns().nodes().length;
var j = 1;
while(j < nb_cols){
var pageTotal = api
.column( j, { page: 'current'} )
.data()
.reduce( function (a, b) {
return Number(a) + Number(b);
}, 0 );
// Update footer
$( api.column( j ).footer() ).html(pageTotal);
j++;
}
}
});
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.21/b-1.6.2/b-colvis-1.6.2/b-html5-1.6.2/b-print-1.6.2/cr-1.5.2/fc-3.3.1/kt-2.5.2/r-2.2.5/rg-1.1.2/rr-1.2.7/sp-1.1.1/sl-1.3.1/datatables.min.css"/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/jszip-2.5.0/dt-1.10.21/b-1.6.2/b-colvis-1.6.2/b-html5-1.6.2/b-print-1.6.2/cr-1.5.2/fc-3.3.1/kt-2.5.2/r-2.2.5/rg-1.1.2/rr-1.2.7/sp-1.1.1/sl-1.3.1/datatables.min.js"></script>
<style>
</style>
</head>
<table id="def-table1" class="def-table1" cellspacing="0" width="100%">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">A</th>
<th scope="col">B</th>
<th scope="col">C</th>
<th scope="col">D%</th>
<th scope="col">E</th>
<th scope="col">F</th>
<th scope="col">G</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
<tbody>
<tr>
<td>1</td>
<td class="minutes">41</td>
<td class="minutes">14</td>
<td class="minutes">33</td>
<td class="minutes">42.4 %</td>
<td class="minutes">42</td>
<td class="minutes">1.02</td>
<td class="minutes">8</td>
</tr>
<tr>
<td>2</td>
<td class="minutes">8</td>
<td class="minutes">2</td>
<td class="minutes">6</td>
<td class="minutes">33.3 %</td>
<td class="minutes">5</td>
<td class="minutes">0.63</td>
<td class="minutes">1</td>
</tr>
<tr>
<td>3</td>
<td class="minutes">29</td>
<td class="minutes">11</td>
<td class="minutes">25</td>
<td class="minutes">44.0 %</td>
<td class="minutes">33</td>
<td class="minutes">1.14</td>
<td class="minutes">5</td>
</tr>
<tr>
<td>4</td>
<td class="minutes">7</td>
<td class="minutes">1</td>
<td class="minutes">5</td>
<td class="minutes">20.0 %</td>
<td class="minutes">5</td>
<td class="minutes">0.71</td>
<td class="minutes">1</td>
</tr>
</tbody>
</table>
I simplified this down by not using this.api() and only using the arguments passed to the callback and some basic array methods. Should be easier to work with now
function tfootTotals(tfRow, data, start, end, display) {
// display is array of data indices that are included in this view
const pageData = data.filter((arr, i) => display.includes(i));
// create array of column totals
const totals = Array.from(pageData[0]).fill(0);
pageData.forEach(arr => arr.forEach((e, i) => totals[i] += (+e) || 0));
// calculate the special ones
totals[4] = (100 * totals[2] / totals[3]).toFixed(1) + '%';
totals[6] = totals[5] / totals[1];
// set the tfoot cell text. slice ignores first one
// so indexing is one less than totals array
$(tfRow.cells).slice(1).text(i => totals[i+1])
// console.log(totals)
}
// DataTable initialisation
$('#def-table1').DataTable({
"searching": false,
"info": false,
"paging": false,
"autoWidth": true,
"footerCallback": tfootTotals
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.js"></script>
<table id="def-table1" class="def-table1" cellspacing="0" width="100%">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">A</th>
<th scope="col">B</th>
<th scope="col">C</th>
<th scope="col" class="col-d">D%</th>
<th scope="col">E</th>
<th scope="col" class="col-f">F</th>
<th scope="col">G</th>
</tr>
</thead>
<tfoot>
<tr>
<td>Totals</td>
<td></td>
<td></td>
<td></td>
<td>ff</td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
<tbody>
<tr>
<td>1</td>
<td class="minutes">41</td>
<td class="minutes">14</td>
<td class="minutes">33</td>
<td class="minutes">42.4 %</td>
<td class="minutes">42</td>
<td class="minutes">1.02</td>
<td class="minutes">8</td>
</tr>
<tr>
<td>2</td>
<td class="minutes">8</td>
<td class="minutes">2</td>
<td class="minutes">6</td>
<td class="minutes">33.3 %</td>
<td class="minutes">5</td>
<td class="minutes">0.63</td>
<td class="minutes">1</td>
</tr>
<tr>
<td>3</td>
<td class="minutes">29</td>
<td class="minutes">11</td>
<td class="minutes">25</td>
<td class="minutes">44.0 %</td>
<td class="minutes">33</td>
<td class="minutes">1.14</td>
<td class="minutes">5</td>
</tr>
<tr>
<td>4</td>
<td class="minutes">7</td>
<td class="minutes">1</td>
<td class="minutes">5</td>
<td class="minutes">20.0 %</td>
<td class="minutes">5</td>
<td class="minutes">0.71</td>
<td class="minutes">1</td>
</tr>
</tbody>
</table>
I have a table in html and the first column in each row contains a date. I want to give some sort of separation based on date. So all rows with todays date would be dark grey, yesterdays row would be light grey and then two days ago would be a grey again and so on.
Is there an easy way to do this?
Thanks
To have alternating rows a different colour (with multiple rows having the same date), you'll have to use jQuery to iterate through all the table rows to check whether it should color that row or not.
Below is the jQuery, HTML and CSS for an example.
// iterate over each row
var tableDate = $("#MyTable tbody").parents('tr:first').find('td:first').text();
var shouldColor = true
$("#MyTable tbody tr").each(function(i) {
// find the first td in the row
var value = $(this).find("td:first").text();
// display the value in console
if (value == tableDate) {
if (shouldColor == true) {
$('#MyTable tbody tr:nth-child(' + (i + 1) + ')').addClass("alternate");
}
} else {
if (shouldColor == false) {
shouldColor = true
$('#MyTable tbody tr:nth-child(' + (i + 1) + ')').addClass("alternate");
} else {
shouldColor = false
}
}
tableDate = value
});
#MyTable {
width:100%;
border-collapse:collapse;
}
#MyTable td {
padding:7px; border:blue 1px solid;
}
#MyTable tr {
background: light-grey;
}
#MyTable .alternate {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table id="MyTable" >
<tbody>
<tr>
<td>4/4/2016</td> <td>Running</td>
</tr>
<tr>
<td>4/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>5/4/2016</td> <td>Running</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>7/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>7/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>8/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>9/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>10/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>11/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>11/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
</tbody>
</table>