Using JQuery to sum integers within table, then find the largest sum - javascript

I have a large HTML table that is updated automatically every 24 hours with new data. the 5th column contains multiple numbers in each row separated by a line break, each containing class .remaining-detail. I'm looking to add the numbers from each row, and then find which row contains the largest sum from column 5.
<table>
<tr class="row-3 odd">
<td class="column-1 ">ID</td><br><br><td class="column-2 "> Name<br>
<br><td class="column "> Area<br>
<br>
</td><td class="column-3 ">$5</td><td class="column-4 "> <div class="remaining-detail">$100,000.00</div>
<div class="remaining-detail">$10,000.00</div>
<div class="remaining-detail">$1,000.00</div>
<div class="remaining-detail">$500.00</div>
<div class="remaining-detail">$400.00</div>
<div class="remaining-detail">$100.00</div><br><br>
</td><td class="column-5 "> <div class="remaining-detail">1</div><br>
<div class="remaining-detail">0</div><br>
<div class="remaining-detail">36</div><br>
<div class="remaining-detail">64</div><br>
<div class="remaining-detail">100</div><br>
<div class="remaining-detail">972</div><br>
</td>
</tr></table>
<br>
I am adding these numbers like this:
$(document).ready(function(){
var sum = 0;
$('.row-2 .column-5 .remaining-detail').each(function () {
sum += parseInt($(this).html().replace(',',''));
});
$('#sum2').text(sum);
});
This works for a single instance. How would I go about doing this for .ROW N .column-5 .remaining-detail and then find the row with the largest sum?
Here is a fiddle with what I have right now: http://jsfiddle.net/3LHb8/

You can do that with two nested .each() loops. Here's an example:
$(document).ready(function(){
var sums = [];
$('tbody tr').each(function() {
var rowSum = 0;
$(this).find('.remaining-detail').each(function () {
rowSum += parseInt($(this).html().replace(',',''));
});
sums.push(rowSum);
});
$('#sum2').text("Biggest sum is in row " + (1 + sums.indexOf(Math.max.apply(Math, sums))));
});
Here's the jsFiddle. I'm storing the sums of each row and then printing the row with the highest sum, but you can do whatever variation you need. Hope it helps.

Hoefully this is what you are looking for
$(document).ready(function(){
var maxsum = 0;
$(".column-5").each(function(){
alert('inside');
var coloumnSum = 0;
$(this).find(".remaining-detail").each(function(){
coloumnSum = coloumnSum + parseInt($(this).html(), 10);
});
if(maxsum < coloumnSum){
maxsum = coloumnSum;
}
});
alert(maxsum);
});

It's hard to tell with no html... Can you share at least 2 rows of your html table and we can help.
oh well, you can try something like this:
var sum = 0;
var sum2 = 0;
var trIndex = 0;
$('.row-2 .column-5').each(function () {
sum = 0;
$(this').find('.remaining-detail').each(function () {
sum += parseInt($(this).html().replace(',',''));
});
if (sum > sum2)
{
sum2 = sum;
trIndex = $(this).parents('tr').index();
}
});
}
alert('row='+trIndex+' sum='+sum2);
$('tr').eq(trIndex-1).css('background-color','#ff0000');
EDIT
Thanks for sharing some html, let us know if the example code we provide works for you :)

Related

How can I display the sum of certain columns of a table in javascript?

I do not understand javascript at all, I study as needed and I need help
I need to sum up the values of certain columns of a table, the rows of which are marked with a checkbox
For example: I mark the checkbox in two rows of the table and the sum of 3,4 and 5 columns is summed up and displayed somewhere on the page
Now I managed to find a piece of code that summarizes the value of the checked checkboxes in the form, and displays it on the page
I need help in replacing the part that receives the "value" of the input, with the one that gets the values of the cells in the stob = head of the table and sums them
Here is this code
var
$form = $("#out_form"),
$allCheckboxes = $("input:checkbox", $form),
$sumOut = $("#checked-sum"),
$countOut = $("#checked-count");
$allCheckboxes.change(function() {
var
sum = 0,
count = 0;
$allCheckboxes.each(function(index, el) {
var
$el = $(el),
val;
if ($el.is(":checked")) {
count++;
val = parseFloat($el.val());
if (!isNaN(val)) {
sum += val;
}
}
});
$sumOut.text(sum);
$countOut.text(count);
});
HTML
<form action="" method="post" id="out_form">
<input type="hidden" name="next" value="{{next}}"/>
<button type="submit">Check</button>
<span id="checked-sum">0</span>
<span id="checked-count">0</span>
{%csrf_token%}
<div class="table-view__container">
<table class="table-view__table">
<tbody class="table-view__body">
{% for out in filter.qs %}
<tr>
<td>
<label class="custom_Label">
<input type="checkbox" name="checked" value="{{ out.id }}">
<span class="checkmark"></span>
</label>
</td>
<td>{{out.date|date:"d(D).m.Y"}}</td>
<td>{{out.ts}}</td>
<td>{{out.pl}}</td>
<td>{{out.rem}}</td>
<td>{{out.comment}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</form>
It is necessary to sum these 3 columns:
...
<td>{{out.ts}}</td>
<td>{{out.pl}}</td>
<td>{{out.rem}}</td>
...
UPD:
I managed to display the amount with the checkbox active, but only the first line:
var
$form = $("#out_form"),
$table = $(".table-view"),
$allCheckboxes = $("input:checkbox", $form),
$sumOut = $("#checked-sum"),
$countOut = $("#checked-count");
$allCheckboxes.change(function() {
var
sum = 0,
count = 0;
$allCheckboxes.each(function(index, el) {
var
$el = $(el),
val;
if ($el.is(":checked")) {
count++;
$form.each(function () {
var val1 = parseInt(document.querySelector(".ts", this).innerHTML,10);
var val2 = parseInt(document.querySelector(".pl", this).innerHTML,10);
var val3 = parseInt(document.querySelector(".rem", this).innerHTML,10);
var total = (val1 * 1) + (val2 * 1) + (val3 * 1);
sum += total;
});
if (!isNaN(val)) {
sum += total;
}
}
});
$sumOut.text(sum);
$countOut.text(count);
});
JavaScript can be confusing, its definitely not an easy programming language. Sorry for not using your code, but I think its overcomplicating things.
So mainly what this code does is to trigger a function using event handlers on all checkboxes, that sums or substracts from the result variable depending if they are checked or unchecked and then show the result in a <span> tag.
Some key points
I used document.querySelectorAll('input[type=checkbox]') to get all the checkbox elements.
The following code is to create one event handler for each checkbox element:
boxes.forEach((box) => {
box.addEventListener("change", function() {
The input checkbox element lives inside a <td></td>, so this.closest('td').nextElementSibling is necessary to get the parent tag and then with the help of nextElementSibling we can get the next <td> element of the table which has the value we need to sum or substract.
Snippet
var boxes = document.querySelectorAll('input[type=checkbox]'),
show = document.getElementById('showResult'), result = 0;
boxes.forEach((box) => {
box.addEventListener("change", function() {
var firstElement = this.closest('td').nextElementSibling,
secondElement = firstElement.nextElementSibling,
firstValue = parseInt(firstElement.innerHTML),
secondValue = parseInt(secondElement.innerHTML);
var sum = firstValue + secondValue;
this.checked ? result += sum : result -= sum;
show.innerHTML = result;
});
});
td {
border: 1px solid #dddddd;
text-align: left;
width:50px;
text-align:center;
}
span{
font-size:20px;
}
<table id="table">
<tr>
<td><input type="checkbox" id="box1" /></td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td><input type="checkbox" id="box2" /></td>
<td>3</td>
<td>4</td>
</tr>
</table>
<br>
<br>
<span>Result: </span><span id="showResult">0</span>

Javascript: Don't sum elements that are not visible

I'm trying to sum a list of values from HTML elements, but I want to EXCLUDE values are that hidden using pure JS.
HTML:
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>
JS:
window.addEventListener('load', function() {
let gramdivs = document.getElementsByClassName("grams");
let milligramdivs = document.getElementsByClassName("milligrams");
var total = 0;
for (let item of gramdivs) {
let itemPrice=parseFloat(item.textContent);
total += itemPrice;
}
for (let item of milligramdivs) {
let itemPrice=parseFloat(item.textContent);
total = total + itemPrice / 1000;
}
document.getElementsByClassName("servings")[0].innerText = total.toFixed(3);
})
https://jsfiddle.net/smhok7yd/2/
In the JS Fiddle, you can see that all the numbers are being added, including the hidden one.
The correct output should be 1.102.
Please note that I cannot change the hierarchy of the HTML.
I am relatively new to JS and have been trying to find a solution all day.
When iterating over elements, check to see if their offsetParent is null - if so, they're not visible:
const getClassValues = (className, multiplier = 1) => [...document.getElementsByClassName(className)]
.filter(elm => elm.offsetParent !== null)
.reduce((a, b) => a + (b.textContent * multiplier), 0);
document.querySelector('.servings').textContent = (
getClassValues('grams') + getClassValues('milligrams', 0.001)
);
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>
If you set display: none; on the specific grams div you can check for the property before adding it to the total:
https://jsfiddle.net/et6wzph2/28/
function isVisible(e) {
return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}
window.addEventListener('load', function() {
let gramdivs = document.getElementsByClassName("grams");
let milligramdivs = document.getElementsByClassName("milligrams");
let total = 0;
for (let item of gramdivs) {
if(!isVisible(item)) continue;
let itemPrice = parseFloat(item.textContent);
total += itemPrice;
}
for (let item of milligramdivs) {
if(!isVisible(item)) continue;
let itemPrice = parseFloat(item.textContent);
total = total + itemPrice / 1000;
}
document.getElementsByClassName("servings")[0].innerText = total.toFixed(3);
})
<div class="grams">1</div>
<div style="display: none;">
<div class="grams">2</div>
</div>
<div class="milligrams">100</div>
<div class="milligrams">2</div>
<br>
<div>Total:</div>
<div class="servings"></div>

How can I write an array values to different paragraphs in a html document using javascript/jquery?

Please, I want to print out the contents of an array to different blocks of paragraphs in HTML using javascript or jquery. I can console.log the problem but can write all individually to different paragraphs of the HTML document I need that to appear at.my source code screenshot in js
// Latest
$(document).each(function() {
var price = [];
var oldprice = [];
var discount;
var i;
$('.price').children('p').each(function() {
price.push(this.innerHTML);
});
$('.old-price').children('p').each(function() {
oldprice.push(this.innerHTML);
});
$(function(){
for(i=0;i <= ((oldprice.length)&&(price.length));i++) {
var mainprice = price[i].replace("₦",""); //new price
mainprice = parseFloat(mainprice.replace(",",""));
var oldmainprice = oldprice[i].replace("₦",""); //oldprice
oldmainprice = parseFloat(oldmainprice.replace(",",""));
var disc = oldmainprice - mainprice;
var pectDisc = (disc / oldmainprice) * 100;
pectDisc = parseInt(pectDisc);
// console.log("-" + pectDisc + "%");
var prices = [];
var offs = [];
prices.push(pectDisc);
for(var x in prices) {
if($(".off")) {
$(".off").text("-" + prices[x] + "%");
// console.log(prices[x]);
}
}
};//end of for loop
});
});
<div class="asses-product">
<div class="pd">
<div class="img"><img src="img/Products/laptop.png" alt="product-image"></div>
<div class="product-description">
<div class="product-name"><h4>Hp Laptop Envy 14</h4></div>
<div class="price"><p>₦ 256,000</p></div>
<div class="old-price"><p>₦ 300,000</p></div>
<div class="off"></div>
</div>
</div>
<div class="pd">
<div class="img"><img src="img/Products/printer.png" alt="product-image"></div>
<div class="product-description">
<div class="product-name"><h4>Hp printer series 10</h4></div>
<div class="price"><p>₦ 12,500</p></div>
<div class="old-price"><p>₦ 18,000</p></div>
<div class="off"></div>
</div>
</div>
</div>
You can do all that with this code:
$(".product-description").each(function () {
// Get price within this container, and remove all non-digits
let price = $(".price", this).text().replace(/\D/g, "");
let oldprice = $(".old-price", this).text().replace(/\D/g, "");
let disc = oldprice - price;
let pectDisc = Math.floor((disc / oldprice) * 100);
$(".off", this).text("-" + pectDisc + "%");
});
This will treat each block with class "product-description" one by one (since they don't effect each other's result). Within those blocks you can retrieve the elements you need by limiting the scope to this.
Digits can be extracted easily by removing anything that is not a digit. The regular expression \D matches any non-digit.
Don't use parseInt to remove decimals from a number. Use Math.floor instead, which avoids the unnecessary string-conversion that parseInt applies.
Some of the errors in your code:
The end-condition of the outer for loop is wrong:
i < ((oldprice.length)&&(price.length))
This should be:
i < oldprice.length && i < price.length
... and really, both lengths should be the same, so you could have simplified to:
i < oldprice.length
Another error is the inner for loop. It does not get to the right .off element. It always selects them all, and sets them all to the same text. Instead, your code should have retrieved the right instance among the many .off elements, and only set the text of that one.
You could have fixed that by replacing that inner loop with this code:
$(".off").eq(i).text("-" + prices[x] + "%");
But all in all, I think the approach I have taken at the start of my answer is better: instead of collecting the prices in an array, just deal with each section one by one.
The error is on your for loop condition.
Your array has 2 element but your condition has 3 loop. so change <= condition to <.
for(i=0;i < ((oldprice.length)&&(price.length));i++) {
see snippet:
// Latest
$(document).each(function() {
var price = [];
var oldprice = [];
var discount;
var i;
$('.price').children('p').each(function() {
price.push(this.innerHTML);
});
$('.old-price').children('p').each(function() {
oldprice.push(this.innerHTML);
});
$(function(){
for(i=0;i < ((oldprice.length)&&(price.length));i++) {
var mainprice = price[i].replace("₦",""); //new price
mainprice = parseFloat(mainprice.replace(",",""));
var oldmainprice = oldprice[i].replace("₦",""); //oldprice
oldmainprice = parseFloat(oldmainprice.replace(",",""));
var disc = oldmainprice - mainprice;
var pectDisc = (disc / oldmainprice) * 100;
pectDisc = parseInt(pectDisc);
// console.log("-" + pectDisc + "%");
var prices = [];
var offs = [];
prices.push(pectDisc);
for(var x in prices) {
if($(".off")) {
$(".off").text("-" + prices[x] + "%");
// console.log(prices[x]);
}
}
};//end of for loop
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="asses-product">
<div class="pd">
<div class="img"><img src="img/Products/laptop.png" alt="product-image"></div>
<div class="product-description">
<div class="product-name"><h4>Hp Laptop Envy 14</h4></div>
<div class="price"><p>₦ 256,000</p></div>
<div class="old-price"><p>₦ 300,000</p></div>
<div class="off"></div>
</div>
</div>
<div class="pd">
<div class="img"><img src="img/Products/printer.png" alt="product-image"></div>
<div class="product-description">
<div class="product-name"><h4>Hp printer series 10</h4></div>
<div class="price"><p>₦ 12,500</p></div>
<div class="old-price"><p>₦ 18,000</p></div>
<div class="off"></div>
</div>
</div>
</div>

Adding sum of array with pushed input values

I have pushed an input value to an empty array and converted it into a number. I am trying to add up the array and show the sum. But the whole array is shown and no addition has been done. I've included some of the code here but I'll also include the JS fiddle in case I forgot something important. I may be overthinking it as I have been looking at it for sometime.
JS Fiddle: https://jsfiddle.net/nzart/emruz0sb/4/
// HTML
<h1>Sugar Counter:</h1><p id="total">--</p>
<div class="box bot1">
<div class="twogrid mid">
<label for="amount">Amount of Sugar</label>
<input type="text" name="amount" id="amount">
</div>
</div>
//JS
var added = [];
//Get Data
var userInput = function(){
return parseFloat(document.getElementById('amount').value);
}
// Store Data
var newSugar = function(){
return added.push(userInput());
}
//Add total
function total() {
var sum = 0;
for (var i = 0; i < added.length; i++) {
sum += added[i];
}
document.getElementById('total').textContent = added;
}
This line is incorrect inside of function total():
document.getElementById('total').textContent = added;
Change to this:
document.getElementById('total').textContent = sum;
Here is an updated fiddle: https://jsfiddle.net/bqt1mws7/
You are displaying the array variable not the sum variable. Assign the sum variable to #total, not added variable.
document.getElementById('total').textContent = sum;
You need a button to perform the summation to update the total.
The Array.prototype.reduce function is a easy way to total values inside of a list.
values.reduce((runningTotal, currentValue) => runningTotal + currentValue, initialValue)
var valueList = [];
document.getElementById('btn-add').addEventListener('click', onAddClick);
function onAddClick(e) {
var value = getCurrentValue();
if (isNaN(value)) {
alert('Value is not a number!');
return;
}
valueList.push(value);
document.getElementById('total').textContent = getTotal();
}
function getCurrentValue() {
return parseFloat(document.getElementById('amount').value.trim());
}
function getTotal() {
return valueList.reduce((a, b) => a + b, 0); // Sum the values in the list
}
<h1>Sugar Counter:</h1>
<label>Total:</label>
<span id="total">--</span>
<div class="box bot1">
<div class="twogrid mid">
<label for="amount">Amount of Sugar</label>
<input type="text" name="amount" id="amount">
<input type="button" value="Add" id="btn-add" />
</div>
</div>
There is no problem in the addition process. If the array is valid, the total() function will work well. But at the last statement of total() function, you put added variable as output. But it should be the value of sum variable.
function total() {
var sum = 0;
for (var i = 0; i < added.length; i++) {
sum += added[i];
}
document.getElementById('total').textContent = sum;
}

Auto calculate sum of data attribute in pure JavaScript

I have tried for so long now to auto calculate the sum of data attribute when adding/removing something to a shopping basket from and calculate the total of data attribute in pure JavaScript no Jquery without being able to fix it! I am pretty new to JavaScript...
Here is my code:
HTML:
//The shopping basket section
<div id="basket">Shopping Basket</div>
<ul class="cart" id="cart_id">
</ul>
<form>
<br>Total Price:
<input type="text" name="totalPrice" id="totalPrice" value="€ 0" disabled>
</form>
<div>
//The category selection section
<ul class="products" id="product_id">
<li class="cat" id="cat_id" name="data" data-title="iPad" data-price="299">iPad (€299)<img class="plusicon" src="plusicon.jpg" alt="plusicon"/></li>
<li class="cat" id="cat_id" name="data" data-title="iPad Air" data-price="399">Ipad Air (€399)<img class="plusicon" src="plusicon.jpg" alt="plusicon"/></li>
<li class="cat" id="cat_id" name="data" data-title="Sony Xperia Z2" data-price="399">Sony Xperia Z2 (€399)<img class="plusicon" src="plusicon.jpg" alt="plusicon"/></li>
<li class="cat" id="cat_id" name="data" data-title="Samsung Galaxy Tab 10,1" data-price="349">Samsung Galaxy Tab 10,1 (€349)<img class="plusicon" src="plusicon.jpg" alt="plusicon"/></li>
</ul>
JS :
function init(){
plus = [].slice.call(document.querySelectorAll(".plusicon"), 0);
for (var i = 0; i < plus.length; i++) {
plus[i].addEventListener("click", addToBasasket, false);
}
}
function addToBasket (e) {
e.stopPropagation();
var ele = info[plus.indexOf(this)];
var title = ele.getAttribute("data-title");
var price = parseInt(ele.getAttribute("data-price"));
var ul = document.getElementById("cart_id");
var li = document.createElement("li");
var remove = document.createElement("img");
remove.className = "removeicon";
remove.src = "removeicon.jpg";
remove.addEventListener("click", removeThingFromList, false);
li.appendChild(remove);
li.appendChild(document.createTextNode(title+" (\u20AC"+price+")"));
ul.appendChild(li);
//So when you press "plusicon" it adds to shopping basket and when you press "removeicon" it deletes from the basket!
//Here below is my problem, I have tried for so long but I cant get to work
//to show the total price when adding and removing li to basket!
var total = 0;
listItem = ele.getAttribute("data-price");
for (var i=0; i < listItem.length; i++)
{
total += parseInt(ele.getAttribute("data-price"));
}
document.querySelector("#totalPrice").value = total;
//I have tried so many different ways but can't get it to work the total of attribute("data-price")!
//This functions below works and removes the current li
function removeThingFromList(e){
this.parentNode.parentNode.removeChild(this.parentNode);
}
}
I hope someone can help! Thanks in advance!
You have to store the price in some attribute in new items (li) added to your basket :
li.appendChild(remove);
//Storing price in data-price attribute
li.setAttribute("data-price", price);
li.appendChild(document.createTextNode(title+" (\u20AC"+price+")"));
ul.appendChild(li);
And after that you can get this attribute and calculate the total :
var total = 0;
var listItem = document.getElementById("cart_id").getElementsByTagName("li");
for (var i=0; i < listItem.length; i++)
{
total += parseInt(listItem[i].getAttribute("data-price"));
}
<ul>
<li class="cart_item" data-prize="12.6" data-id="5">Hello €12.6</li>
<li class="cart_item" data-prize="4.25" data-id="8">World €4.25</li>
<li class="cart_item" data-prize="13.8" data-id="9">Foo €13.8</li>
<li class="cart_item" data-prize="6.3" data-id="12">Bar €6.3</li>
</ul>
<input type="button" value="TOTAL" onclick="calculateTotal();">
<div id="messages"></div>
<script>
function data(elm, key) {
for(var i in elm.attributes) {
if ( elm.attributes[i].name.substr(0, 5) === 'data-' ) { // checks if the 5 first letters of the attribute are 'data-'
// it's a data- attribute. Now let's see if it's the right one
if ( elm.attributes[i].name.substr(5) === key) { // checks if the letters, next to the 5 first letters, correspond with the key we need
return elm.attributes[i].value;
}
}
}
return '';
}
function calculateTotal() {
document.getElementById("messages").innerHTML = '';
var items = document.getElementsByClassName("cart_item");
var sum=0;
for (var i in items) {
var prize = Number( data(items[i], 'prize') ); // without the Number(), it's seen as text
sum += prize;
if(prize) { // else it also shows blank lines
document.getElementById("messages").innerHTML += prize + '<br>';
}
}
document.getElementById("messages").innerHTML += '+ -----<br>' + sum;
}
</script>

Categories