I want to grab all the values from the label with class price and add them using jQuery. Now actual webpage is different but to understand the concept I am only putting minimum code here. There are 3 labels for prices, and 1 more for total:
<label class="price">120</label>
<label class="price">250</label>
<label class="price">342</label>
<label id="total"></label>
I read that .each() can be used but I could not understand how to use it for this purpose.
I have uploaded jsfiddle over here http://jsfiddle.net/vivpad/cysjtrh8/1/
Basic example
jQuery(document).ready(function($){
var total = 0;
$('label.price').each(function(){
var value = parseFloat($(this).text());
total += value;
});
$('#total').text(total);
});
DEMO
You could get total price mapping .price elements text:
jQuery(document).ready(function ($) {
$('#total').text(function () {
return $('.price').map(function () {
return +$(this).text()
}).get().reduce(function (pv, cv) {
return pv + cv;
}, 0);
});
});
-jsFiddle-
Note that you need to add jquery to your jsfiddle.
Also - you don't need to use .each - you can use arrays as well. Which simplifies it much and it is more efficient. See here: http://jsfiddle.net/vivpad/cysjtrh8/9
var sum = 0;
var prices = $("label.price");
for (var i = 0; i < prices.length; i++)
sum += parseInt($(prices[i]).text());
$("#total").text(sum);
try this:
jQuery(document).ready(function($){
var total = 0;
$('.price').each(function() {
var temp = $(this).html();
total += parseFloat(temp);
});
$('#total').html(total);
});
JsFiddle
Try:
var labelvalues = $('label').map(function () {
return $(this).text();
}).get();
var total = 0;
for (var i = 0; i < labelvalues.length; i++) {
total += labelvalues[i] << 0;
}
$("#total").text(total);
DEMO
Here I am using map function to translate all items to new array of items. And add the elements in the array.
Related
I am trying to calculate the average of 3 values (each numbered from 1-10) that are selected by the user and then pass the results to an text input (for display as a graph).
It should be updating the new average every time one of the values is changed, but the averaging is not working correctly at all. I think that the loop is not resetting the values every time it runs- it's adding up the sum each time it runs, but not sure how to fix it.
Here is my code:
var sliders = $("#health1,#health2,#health3");
var elmt = [];
$(sliders).each(function () {
elmt.push($(this).attr('value'));
$("#health1,#health2,#health3").change(function () {
var sum = 0;
averageRisk();
});
});
function averageRisk() {
var sum = 0;
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i], 10);
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
elmt.push($(sliders).attr('value'));
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
Here is an example:
http://jsfiddle.net/pixelmix/783cfmnv/
Not sure but seems like a lot of extra work going. Main issue was you were building array of initial values and not getting the values each time they changed. That first .each got all the slider values and added them to elmt and continued to push new values on to after every change instead of just getting the current values every time. Did you want to accumulate all values over time?
Fiddle: http://jsfiddle.net/AtheistP3ace/783cfmnv/6/
$("#health1,#health2,#health3").on('change', function () {
averageRisk();
});
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
And as pointed out if you want to ignore updating things when the sum is NaN you can do this:
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
if (isNaN(sum)) {
return false;
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
The problem is that you fill the elmt array at page loading.
When user changes the values, you do not refresh the elmt array. So the array used to compute the average is always the same, empty.
You have to recover the input values each time they are modified.
function averageRisk() {
var sum = 0;
// Re make the loop for getting all inputs values
$(sliders).each(function() {
var value = parseInt($(this).val(), 10);
sum += value;
});
var avg = sum/$(sliders).length;
$('#healthLevel').val(avg);
}
Working example : http://jsfiddle.net/783cfmnv/7/
PS : You can use the css class healthInput to select your inputs. If you add later other fields, you will not have to add the new input id to your jQuery selector.
I did this work, check it .
http://jsfiddle.net/783cfmnv/10/
$("#health1,#health2,#health3").change(function() {
var val1 = +slider1.val();
var val2 = +slider2.val();
var val3 = +slider3.val();
var avg = (val1 + val2 + val3) /3;
$("#healthLevel").val(avg);
});
I have the code to total a column, but I have subgroups that already have totals. Can I total each number in the column EXCEPT the gray total rows?
var table = $('#datatable');
var leng = table.find("tr:first").children().length;
// add totals to new row
for (var i = 0; i < leng; i++) {
var total = api
.column(i)
.data()
.reduce(function (a, b) {
// return if it's not a value from the gray row
return intVal(a) + intVal(b);
});
// correct any html mistakes that slip through
if (isNaN(intVal(total)))
total = '';
table.find("tfoot tr:first th").eq(i).html(total);
};
Why not just use the :not selector on the rows() API method and calculate the sum based on the remaining rows? Very small example, add the sum of col#1 to the footer in a callback :
var table = $('#example').DataTable({
drawCallback: function () {
var api = this.api(),
sum = 0;
api.rows(":not('.sgrouptotal')").every(function() {
sum += parseFloat(this.data()[0]);
});
$(api.column(0).footer()).text(sum);
}
});
demo -> http://jsfiddle.net/j38bmagj/
The above should be fairly easy to extend to multiple columns. Calculate the sum for col #4 in the same loop like sum4 += this.data()[4] and so on.
What about just doing that?
i = 0;
$('#datatable tr:first tr').each(function(key, value){
if(!$(this).hasClass("sgrouptotal"){
i += parseInt(value.text());
}
});
i got a group of inputs... each one has a number value.
i want to get all their values (found a method here) and then compare
then and highlight the heighest input meaning highlight the input itself
meaning i need to somehow grab its id and know which one i am comparing to...
(i hope i explained it good).
This is what i have for now taken from the link attached:
var values = [];
$("input[name='items[]']").each(function() {
values.push($(this).val());
});
try something like this
$(function(){
var higesht_val = 0;
var higesht_val_id = 0;
$("input[name='items[]']").each(function() {
var current_val = parseInt(this.value);
if(higesht_val < current_val){
higesht_val = current_val;
higesht_val_id = this.id;
}
});
alert(higesht_val); // highest value
alert(higesht_val_id);// id of highest value input
})
var highestVal = 0,
$target;
$("input[name='items[]']").each(function() {
if(parseInt($(this).val()) > highestVal){
highestVal = parseInt($(this).val());
$target = $(this);
}
});
// $target is now the input with the highest value
how about this ?
var values = [];
$("input[name='items[]']").each(function() {values.push(this);});
values.sort(function(a, b){return b.value - a.value;})
highlight(values[0]);
I am having the
table which contains the table like
items price quantity total
apple 100 2 200
orange 200 2 600
grand total=600.
item fields are dropdown when drop down changes the price will be changed and total value and grandtotal also changed. My problem is when selecting apple and orange again go to apple change the item my grand total is not changing.
My Javascript code:
function totalprice(element, price) {
var elementid = element.id;
var expr = elementid.substring(elementid.indexOf(":") + 1, elementid.length);
var quantity = document.getElementById("quantity:" + expr).value;
var price = document.getElementById("price:" + expr).value;
if (quantity > 0) {
document.getElementById("total:" + expr).value = (parseInt(quantity)) * (parseInt(price));
var grandtotal = document.getElementById("total:" + expr).value;
var gtot = 0;
var amount = 0;
for (var i = 0; i <= expr; i++) {
//document.getElementById("total").value="";
gtot = document.getElementById("total:" + expr).value;
amount = parseInt(gtot) + parseInt(amount);
}
document.getElementById("total").value = amount;
}
return true;
}
I know the mistake is in for loop only it is simple one but i dont know how to solve.
I got the solution for this using table rows length and use that length to my for loop now my code is like
function totalprice(element,price)
{
var elementid=element.id;
var expr = elementid.substring(elementid.indexOf(":") + 1, elementid.length);
var quantity = document.getElementById("quantity:"+expr).value;
var price = document.getElementById("price:" + expr).value;
if(quantity >0)
{
document.getElementById("total:"+ expr ).value= (parseInt(quantity))*(parseInt(price));
//var grandtotal =document.getElementById("total:"+expr).value;
//var grandtotal = document.getElementsByClassName("total"+expr);
var rowcount = document.getElementById('table').rows.length;
var grandtotal = 0;
var finalamount = 0;
for(var i=1; i<rowcount; i++)
{
grandtotal=document.getElementById("total:"+i).value;
finalamount = parseInt(grandtotal) + parseInt(finalamount);
}
document.getElementById("total").value=finalamount;
}
return true;
}
Here is code what you need:
Java Script:
<script>
function getVal(e){
// for text
alert(e.options[e.selectedIndex].innerHTML);
// for value
alert(e.options[e.selectedIndex].value);
}
</script>
HTML:
<select name="sel" id="sel" onchange='getVal(this);'>
<option value="1">Apple</option>
<option value="2">Banana</option>
<option value="3">Cat</option>
</select>
I see two errors in your for loop, first you forgot to use i in your getElement so you're only going through the same field multiple times, second, you're only looping through the inputs previous to the field that was updated (i<=expr), when you actually want to go through all the "total" fields to get the grand total, I would suggest giving a class to all your total fields and then use this code for your loop
var total_fields = document.getElementsByClassName('total');
for (var i = 0; i < total_fields.length; i++) {
gtot = total_fields[i].value;
amount+= parseInt(gtot);
}
document.getElementById("total").value = amount;
I think the problem relies here:
"My problem is when selecting apple and orange again"
Because I don't see in your code that you are actually updating the elements id when you calculate the total.
So... If you do:
gtot = document.getElementById("total:" + expr).value;
First time will work, because expr var is the original one, then, gtot is the right element id
but...
...when you do a second change, that var has a different value now... and gtot will not match your element id to recalculate the new value. (or in worst case, will match another and update the wrong one)
(forgive me if I use slightly incorrect language - feel free to constructively correct as needed)
There are a couple posts about getting data from JSON data of siblings in the returned object, but I'm having trouble applying that information to my situation:
I have a bunch of objects that are getting returned as JSON from a REST call and for each object with a node of a certain key:value I need to extract the numeric value of a sibling node of a specific key. For example:
For the following list of objects, I need to add up the numbers in "file_size" for each object with matching "desc" and return that to matching input values on the page.
{"ResultSet":{
Result":[
{
"file_size":"722694",
"desc":"description1",
"format":"GIF"
},
{
"file_size":"19754932",
"desc":"description1",
"format":"JPEG"
},
{
"file_size":"778174",
"desc":"description2",
"format":"GIF"
},
{
"file_size":"244569996",
"desc":"description1",
"format":"PNG"
},
{
"file_size":"466918",
"desc":"description2",
"format":"TIFF"
}
]
}}
You can use the following function:
function findSum(description, array) {
var i = 0;
var sum = 0;
for(i = 0; i < array.length; i++) {
if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
sum += parseInt(array[i]["file_size"], 10);
}
}
alert(sum);
}
And call it like this:
findSum("description1", ResultSet.Result);
To display an alert with the summation of all "description1" file sizes.
A working JSFiddle is here: http://jsfiddle.net/Q9n2U/.
In response to your updates and comments, here is some new code that creates some divs with the summations for all descriptions. I took out the hasOwnProperty code because you changed your data set, but note that if you have objects in the data array without the file_size property, you must use hasOwnProperty to check for it. You should be able to adjust this for your jQuery .each fairly easily.
var data = {};
var array = ResultSet.Result;
var i = 0;
var currentDesc, currentSize;
var sizeDiv;
var sumItem;
//Sum the sizes for each description
for(i = 0; i < array.length; i++) {
currentDesc = array[i]["desc"];
currentSize = parseInt(array[i]["file_size"], 10);
data[currentDesc] =
typeof data[currentDesc] === "undefined"
? currentSize
: data[currentDesc] + currentSize;
}
//Print the summations to divs on the page
for(sumItem in data) {
if(data.hasOwnProperty(sumItem)) {
sizeDiv = document.createElement("div");
sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
document.body.appendChild(sizeDiv);
}
}
A working JSFiddle is here: http://jsfiddle.net/DxCLu/.
That's an array embedded in an object, so
data.ResultSet.Result[2].file_size
would give you 778174
var sum = {}, result = ResultSet.Result
// Initialize Sum Storage
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] = 0;
}
// Sum the matching file size
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] += parseInt(result[i]["file_size"]
}
After executing above code, you will have a JSON named sum like this
sum = {
"description1": 20477629,
"description2": 1246092
};
An iterate like below should do the job,
var result = data.ResultSet.Result;
var stat = {};
for (var i = 0; i < result.length; i++) {
if (stat.hasOwnProperty(result[i].cat_desc)) {
if (result[i].hasOwnProperty('file_size')) {
stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);
}
} else {
stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
}
}
DEMO: http://jsfiddle.net/HtrLu/1/