Calculating Sum of table in HTML - javascript

In my web application, I have created table and assigned values for table from controller.
Here I want to show the total of column value Amount at the end of table.
So I have done this so far but It didn't show the total value.
var tds = document.getElementById('PayvouchDt').getElementsByTagName('td');
var sum = 0;
for (var i = 0; i < tds.length; i++) {
sum += parseInt(tds[i].cells[3].innerHTML);
}
document.getElementById('PayvouchDt').innerHTML += '<tr><td>' + sum + '</td><td>Total Value</td></tr>';
<table class="table table-striped" id="PayvouchDt">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
#{int RowNo = 0;} #for (int i = 0; i
< Model.First().PaymentVouchDetails.Count; i++) { <tr>
<td>#{RowNo++;} #RowNo</td>
<td>#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].Details)</td>
<td>#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].CostCenter)</td>
<td class="count-me">Rs.#Html.DisplayFor(Model => Model.First().PaymentVouchDetails[i].Amount)</td>
</tr>
}
</tbody>
</table>

You need the rows. The cells do not have cells
Also an amount normally have decimals so we need them as floats instead of ints
var trs = document.getElementById('PayvouchDt').getElementsByTagName('tr');
var sum = 0;
for (var i = 0; i < trs.length; i++) {
sum += parseFloat(trs[i].cells[3].textContent);
}
document.getElementById('PayvouchDt').innerHTML += '<tr><td>' + sum.toFixed(2) + '</td><td>Total Value</td></tr>';
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="PayvouchDt">
<tr>
<td>1</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">1.50</td>
</tr>
<tr>
<td>2</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">3.20</td>
</tr>
</tbody>
</table>
I suggest to use the tbody and a reduce on the converted textContent
const tds = document.querySelectorAll('#PayvouchDt tr td.count-me'); // or td:nth-child(4)
const sum = [...tds].map(td => +td.textContent).reduce((a, b) => a + b)
document.getElementById('PayvouchDt').innerHTML += `<tr><td>${sum.toFixed(2)}</td><td>Total Value</td></tr>`;
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Description</th>
<th>Cost Center</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="PayvouchDt">
<tr>
<td>1</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">1.50</td>
</tr>
<tr>
<td>2</td>
<td>Details</td>
<td>Costcenter</td>
<td class="count-me">3.20</td>
</tr>
</tbody>
</table>

you can sum the elements of the array simply using the javascript [reduce method][1].
for example
const myArray = [{value: 1, name: 'john'}, {value: 2, name: 'doe'}, {value: 3, name: 'john'}, {value: 4, name: 'doe'}];
const v = myArray.reduce((tot, el) => tot + el.value, 0);
console.log(v)
you can take this snippet and adapt it to your need
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce?retiredLocale=it

Related

how can i get sum of one columns rows? [duplicate]

I am trying to add Price from table column to a total.
I am having problem adding values such as 10.00 or 5.99. I am able to calculate prices with int values, but not with values 10.00 or 5.99, etc.
Here is what I have below.
var table = document.getElementById("myTable"),
sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseF(table.rows[i].cells[2].innerHTML);
}
document.getElementById("val").innerHTML = "SubTotal =" + sumVal;
console.log(sumVal);
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
</table>
<span id="val"></span>
You have three issues:
You are grabbing the wrong cell index, indices start at 0:
table.rows[i].cells[1]
You need to call the correct parse function:
parseFloat(table.rows[i].cells[1].innerHTML);
You need to format your output:
"SubTotal = $" + sumVal.toFixed(2);
Update: Added functionality for removing rows.
updateSubTotal(); // Initial call
function updateSubTotal() {
var table = document.getElementById("myTable");
let subTotal = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[1].innerHTML);
}, 0);
document.getElementById("val").innerHTML = "SubTotal = $" + subTotal.toFixed(2);
}
function onClickRemove(deleteButton) {
let row = deleteButton.parentElement.parentElement;
row.parentNode.removeChild(row);
updateSubTotal(); // Call after delete
}
#myTable td {
padding: 0.25em;
}
#val {
display: block;
margin-top: 0.5em;
}
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoodie</td>
<td class="count-me">15.00</td>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
</table>
<span id="val"></span>
You are accessing the incorrect array element and also need to use parseFloat
The cells array is zero-based so you need to use cells[1] to access the second column:
var table = document.getElementById("myTable"),
sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseFloat(table.rows[i].cells[1].innerHTML);
}
document.getElementById("val").innerHTML = "SubTotal =" + sumVal;
console.log(sumVal);
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td><button onClick="myFunction()">Remove</button></td>
</tr>
</table>
<span id="val"></span>
updateSubTotal(); // Initial call
function updateSubTotal() {
var table = document.getElementById("myTable");
let subTotal = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[1].innerHTML);
}, 0);
let subTotal2 = Array.from(table.rows).slice(1).reduce((total, row) => {
return total + parseFloat(row.cells[2].innerHTML);
}, 0);
document.getElementById("val").innerHTML = "SubTotal = $" + subTotal.toFixed(2);
document.getElementById("val1").innerHTML = subTotal2.toFixed(2);
}
function onClickRemove(deleteButton) {
let row = deleteButton.parentElement.parentElement;
row.parentNode.removeChild(row);
updateSubTotal(); // Call after delete
}
#myTable td {
padding: 0.25em;
}
#val {
display: block;
margin-top: 0.5em;
}
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>M2</th>
<th>Remove</th>
</tr>
<tr>
<td>Hoodie</td>
<td class="count-me">15.00</td>
<td class="count-me">34.00</th>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td class="count-me">22.34</th>
<td><button onClick="onClickRemove(this)">Remove</button></td>
</tr>
</table>
<span id="val"></span>
<span id="val1"></span>
var cell = document.getElementsByClassName("count-me");
var val = 0;
var i = 0;
while (cell[i] != undefined) {
val += parseFloat(cell[i].innerHTML);
i++;
} //end while
document.getElementById("val").innerHTML = parseFloat(val).toFixed(2);
console.log(parseFloat(val).toFixed(2));
<table id="myTable">
<tr>
<th>Item</th>
<th>Price</th>
<th>Remove</th>
</tr>
<tr id="">
<td>Hoddie</td>
<td class="count-me">15.00</td>
<td>
<button onClick="myFunction()">Remove</button>
</td>
</tr>
<tr>
<td>Nike Cap</td>
<td class="count-me">10.99</td>
<td>
<button onClick="myFunction()">Remove</button>
</td>
</tr>
</table>
<span id="val"></span>

How to sort the table to order by points at end of column using javascript

I am trying to sort the table using javascript to order by total points at the end. The table is a dynamic one so W1, W2, W3 columns adds up to total. Is there way to order rows them by total in javascript. Each row is dynamically created as well.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="fl-table">
<thead>
<tr>
<th>Player</th>
<th>Player Name</th>
<!-- <th>W1</th>
<th>W2</th> -->
<th>W1</th>
<th>W2</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Heather Rankin</td>
<td>4</td>
<td>21</td>
<td>25</td>
</tr>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Stephen Puopolo</td>
<td>3</td>
<td>1</td>
<td>4</td>
</tr>
<tr>
<td class="agl-profile-img-new"><img src="https://via.placeholder.com/70
C/O https://placeholder.com/"></td>
<td>Latheesh V M V</td>
<td>2</td>
<td>26</td>
<td>28</td>
</tr>
</tbody>
<tbody>
</tbody>
</table>
Is there is any way? Please help
can you gather the cells into object and sort them like this. https://jsfiddle.net/e4oscnz8/4/
const sortTotal = () => {
const tbl = [...document.getElementsByClassName("fl-table")][0];
const tbody = [...tbl.tBodies][0];
const oObjects = [];
[...tbody.rows].forEach(row => {
const cells = [...row.cells];
const obj = [...row.cells].map(cell => {
return cell.innerHTML;
});
oObjects.push(obj);
});
oObjects.sort((a, b) => a[a.length -2] > b[b.length -2] ? 1 : -1);
[...tbody.rows].forEach((row, i) => {
[...row.cells].forEach((cell, j) => {
cell.innerHTML = oObjects[i][j];
});
});
}
push tr rows into array or object and sort by your custom sort function: https://jsfiddle.net/2dq7m8k9/
you are using jquery so life is good :)
function SortByTotal(tr1, tr2){//descending sorting
var total1 = parseInt(tr1.find('td:last-child').text());
var total2 = parseInt(tr2.find('td:last-child').text());
return ((total1 > total2) ? -1 : ((total1 < total2) ? 1 : 0));
}
var trs=new Array();
$('#mytable tbody').first().children('tr').each(function(){
trs.push($(this).clone());
});
trs.sort(SortByTotal);
$('#mytable tbody').first().empty();
var i=0;
for (i = 0; i < trs.length; i++) {
$('#mytable tbody').first().append(trs[i]);
}

Continue loop through all tbody element and add id to all tr's

I have many tables and I want to give all tr's individual ids. I loop through all tbody but it only affects first tbody, not all of them. When I add loop indicating each tbody they work. Is there any efficient way available to loop through all tbody and give the tr's individual id. I want to do it using vanilla javascript, no jQuery.
My sample code here :
<table><tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody></table>
Javascript :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[i].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
}
Second Try :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[0].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
var y = c[1].rows;
for (i=0; i<y.length; i++){
y[i].setAttribute('id','tr'+_trIndex++)
}
}
Probably this is what you need:
// Instead of getting the table bodies, I get only the table
// rows inside the tbody elements.
var c = document.querySelectorAll('tbody tr');
// Here I check if definitely the above query found any values.
if ( c ) {
// Then I do the itteration to the found tr elements
for ( i = 0; i < c.length; i++) {
// And here I set the ID the same way you did in your example
c[i].setAttribute('id','tr'+i);
}
}
<table>
<tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody>
</table>
You can achieve this with a single line of javascript.
document.querySelectorAll("tbody tr").forEach((element, index) => element.setAttribute("id", "tr" + index));
<table>
<thead>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
</thead>
<tbody>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>01</td>
<td>ted</td>
<td>0.50</td>
</tr>
<tr>
<td>02</td>
<td>joe</td>
<td>0.25</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Address</td>
<td>Phone</td>
</tr>
<tr>
<td>joe</td>
<td>LA</td>
<td>012345</td>
</tr>
<tr>
<td>ted</td>
<td>NY</td>
<td>0124</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Spec</td>
<td>Budget</td>
</tr>
<tr>
<td>joe</td>
<td>i5</td>
<td>458</td>
</tr>
<tr>
<td>ted</td>
<td>i7</td>
<td>768</td>
</tr>
</tbody>
</table>

Hide empty html table rows

Problem
I have a table with one or more empty rows. How to hide empty rows from the table?
For example
1 - John | Alfredo
2 - Mark | Zuck
3 - |
4 - Carl | Johnson
In this case, I'd like to delete the third row.
Step Tried
I found how to delete a specific row, what about deleting all the empty rows?
deleteEmptyRows();
function deleteEmptyRows() {
var myTable = document.getElementById("myTable")
var rowToDelete = 2;
myTable.deleteRow(rowToDelete)
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
</tbody>
</table>
This is how you can dynamically hide empty table rows with javascript.
deleteEmptyRows();
function checkIfCellsAreEmpty(row) {
var cells = row.cells;
var isCellEmpty = false;
for(var j = 0; j < cells.length; j++) {
if(cells[j].innerHTML !== '') {
return isCellEmpty;
}
}
return !isCellEmpty;
}
function deleteEmptyRows() {
var myTable = document.getElementById("myTable");
for(var i = 0; i < myTable.rows.length; i++) {
var isRowEmpty = checkIfCellsAreEmpty(myTable.rows[i]);
if (isRowEmpty) {
myTable.rows[i].style.display = "none";
}
}
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
</tbody>
</table>
Here, a simple method for row is empty (this allows us to check for other conditions easily later).
Loop over rows and call remove if empty.
const rowIsEmpty = (tr) => Array.from(tr.querySelectorAll('td')).every(td => td.innerText === "");
deleteEmptyRows();
function deleteEmptyRows() {
var myTable = document.getElementById("myTable");
myTable.querySelectorAll('tr').forEach(tr => {
if(rowIsEmpty(tr)) tr.remove();
});
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Was answered in another thread.
Jquery: hiding empty table rows
Loops through all table tr rows, and checks td lengths. If the td length is empty will hide.
$("table tr").each(function() {
let cell = $.trim($(this).find('td').text());
if (cell.length == 0){
console.log('Empty cell');
$(this).addClass('nodisplay');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
</tr>
<tr>
<!-- Will hide --> <td></td>
</tr>
</table>
With native Javascript:
function removeRow(src) {
var tableRows = document.getElementById(src).querySelectorAll('tr');
tableRows.forEach(function(row){
if((/^\s*$/).test(row.innerText)){
row.parentNode.removeChild(row);
}
});
}
removeRow('myTable');
The only problem is when you have some other characters in the row, except the whitespaces. This regex checks for blank characters, but if u have a dot inside or any other non empty character, it will fail.

How To Sum All Table Rows td (TotalPrice) using td id Jquery

I am adding values to table like:
Item,Quantity,Price,TotalPrice
Now there are multiple rows: How can i sum TotalPrice of all to get GrandTotal using Jquery.
Code:
$("#Product").append(" <tr><td id='clientname'>" +ClientName+ "</td> <td id='item'>"+ItemName+"</td> <td id='quantity'>"+Quantity+"</td> <td id='price'>"+Price+"</td> <td id='totalprice'>"+TotalPrice+"</td> <td> <a onClick='deleteRow(this);'>Delete</a> </td> </tr>");
Its possible when i insert new row data its show grand total in textbox/label,Like:
function TotalPriceCalc()
{
var lblTotalPrice = document.getElementById('lblTotalPrice');
lblTotalPrice.value = sum;
}
Here's an example that will sum whatever column index you provide.
$(function() {
$("#subtotal").html(sumColumn(4));
$("#total").html(sumColumn(5));
});
function sumColumn(index) {
var total = 0;
$("td:nth-child(" + index + ")").each(function() {
total += parseInt($(this).text(), 10) || 0;
});
return total;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table style="border-spacing: 10px;">
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>12</td>
<td>34</td>
</tr>
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>56</td>
<td>78</td>
</tr>
<tr>
<td>ClientName</td>
<td>ItemName</td>
<td>Quantity</td>
<td>90</td>
<td>12</td>
</tr>
<tr>
<td colspan="3">Totals</td>
<td id="subtotal"></td>
<td id="total"></td>
</tr>
</table>
After you use class= instead of id= .Cause ID MUST be unique. you need to loop through each row and find totalPrice
$(document).ready(function(){
var TotalValue = 0;
$("#Product tr").each(function(){
TotalValue += parseFloat($(this).find('.totalprice').text());
});
alert(TotalValue);
});
While you tagged Jquery .. This is a Jquery solution so please be sure to include Jquery
You should use classes, not IDs, to name repeated elements. So it should be:
...<td class="totalprice">'+TotalPrice+'</td>...
Then you can do
function TotalPriceCalc() {
var total = 0;
$(".totalprice").each(function() {
total += parseFloat($(this).text());
});
$("#lblTotalPrice").val(total);
}
Have look, this is our table
<table class="table table-bordered">
<thead>
<tr>
<th>1</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td id="loop">50</td>
</tr>
<tr>
<td>1</td>
<td id="loop">60</td>
</tr>
<tr>
<td>1</td>
<td id="loop">70</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="text-right">Total</td>
<td></td>
</tr>
</tbody>
And this is loop to have sum of price
$(function() {
var TotalValue = 0;
$("tr #loop").each(function(index,value){
currentRow = parseFloat($(this).text());
TotalValue += currentRow
});
console.log(TotalValue);
});

Categories