Find the sum of all values of spinners with same class - javascript

I have a group of spinners <select> input fields and I want to find the sum of them live. I figured the easiest way would be to use jquery's class selector but it does not store the .val()'s of elements of a similar class in an array.
Is there a way to store all the values of a bunch of <select> Inputs in an array so I can find the sum of all of their values.
My not working code looks like this.
function calcPrice() {
var price = $('.food').val() || [];
}
$("select").change(calcPrice);

This might be overkill, but you could use http://www.pengoworks.com/workshop/jquery/calculation/calculation.plugin.htm
or you could simply do:
var price = 0.0
$(".food'").each(function() {
price += +this.value
});

Would you mind to clarify what are the .food elements? Are they input fields? Otherwise, you may want to try using $('.food').text() instead.

Similar to btiernay's answer, but if you wanted to keep the actual array you can do:
var prices = $.map($(".food"), function () {
return +this.value;
});

var expenses = 0.0;
$(".expense").each(function() {
expenses += +this.value;
});
$("#expense-total").html(expenses);
Basically the same as btiernay but it has missing ; which could fool noobs. Also added jquery element example to push the final value to a sum field. Sorry I could't add as a comment as I rarely post so reputattion less than 50.
Live example under business expeses here: http://contractor.icalculator.info/calculator/PAYE-calculator.html

Related

How to add a class to all similar elements with an index less than the clicked element with jquery?

I have 8 elements in sequence that each represent a yoga pose. When one of these elements is clicked I want to add/remove classes for all the pose cards that come before and after the clicked element. So far I have been able to get the index of the clicked element using the following:
$(".pose-card").click(function () {
clickedPoseIndex = $(".pose-card").index(this);
});
And then I tried to use a filter function to get the ones whose index is less than the clicked one with something like this:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this) < clickedPoseIndex);
});
But that did not work! Please let me know if you can think of any better solutions. Much appreciated!
What you want to do inside filter is get the index as int (hence the parseInt function) and compare with the value you've stored in clickedPoseIndex which is already an int. You've simply missed a bracket or misplaced one. All you have to do is:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this)) < clickedPoseIndex;
});
Edit
Don't need to use parseInt either as the value returned is already an int so:
return $(".pose-card").index(this) < clickedPoseIndex;

Is a recursive function an effective way to add table rows dynamically?

In my research and attempts to use JavaScript to add rows to a HTML Table dynamically, it was important that each id tag be incremented according to the row number. I found various suggested ways of doing this. Finally, I thought I'd give a try at writing a recursive function to do the trick. The following works. But I do not know if it could be optimized. Kindly let me know what I can do to improve it.
function incrementElementID(element, incrementVal) {
if(element.hasAttribute("id")) {
idVal = element.getAttribute("id");
element.setAttribute("id",idVal+incrementVal);
}
var numChildren = element.childElementCount;
for (var i=0; i<numChildren; i++)
incrementElementID(element.children[i],incrementVal);
return;
}
Best done with a closure variable if you're not intentionally trying to use recursion.
Set a variable outside the function scope and increment it within the function.
You're better off with some simple jQuery:
var incrementVal = ...
$("[id]").each(function(index, value) {
elem = $(value);
elem.attr("id", +elem.attr("id") + incrementVal);
});
$("[id]") selects any element that has an id attribute: http://api.jquery.com/has-attribute-selector/
.each iterates through all the items in the collection: https://api.jquery.com/jQuery.each/
The + at the front of +elem.attr("id") converts the attribute value from a string to an int.

Calculating the total of an online order form using javascript

I'm working on a basic order form and I would like to see if I can build it from stratch.
I have a form which is made up of a table with 12 items listed and text input fields for item quantity. What I would like to do is have the code run through the form to check for any quantities that have been entered, then relate these values to the prices in an array.
So far I have the array:
var juicePrice = new Array();
juicePrice["citrusZing"]=20.00;
juicePrice["strawberrySmooth"]=22.00;
juicePrice["carrotSpin"]=21.50;
juicePrice["Tropical"]=20.75;
...
and a way to run through the form:
calculateTotal()
{
var juiceForm = document.forms["juiceform"];
//Get a reference to the juice the user Chooses name=selectedJuiceQty":
var selectedJuiceQty = juiceForm.elements["selectedJuiceQty"];
for(var i = 0; i < selectedJuiceQty.length; i++);
but I'm not quite sure how to connect the information from the form to calculate the totals. Can anyone point me in the right direction? Is it something like this?
for(var i = 0; i < selectedJuiceQty.length; i++){
var juiceTotal = 0;
if(selectedJuiceQty[i]>0) {
juiceTotal += juicePrice[selectedJuiceQty[i].value]*selectedJuiceQty;
//If we get a match then we break out of this loop
break;
}
return total;
}
Is it possible to use the same name tag for each field or should I just use citrusZingQty = parseInt(document.getElementById("citrusZing").value); for each item? Then I would have to list all of the items, which doesn't seem a very elegant way. What would happen if multiple items are selected?
Any help anyone can give to point me in the right direction would be great.
So you can do what you want. Michael pointed this out in the comments but it may have been overlooked.
var myPrices = new Object();
myPrices['eggs'] = 1.50;
myPrices['bread'] = 1.00;
// ...
Then you can loop through your form fields and check against your 'myPrices' object.
EDIT
To answer your question in the comments - I would not use the same name for all of my input fields. It does make looping through the form easier perhaps. However, using the id/class of the input tag is not a nice solution in my opinion. HTML id/class are there for CSS/Javascript manipulation and using it to identify which fruit the input represents will not be apparent to other developers working on the project (I realize this may be a small project for you but it's best not to start any bad habits). I would name each input after the juice/drink it represents.

dojo foreach function

I am quite new to dojo and I'm stuck with a problem here
I have a zend dojo form where I need to take sum of four elements and set the value to another element. I have assigned a class (score) to those four elements
".score" : {
"found" : function (ele) {
var widgetId = ele.getAttribute('widgetid');
dojo.connect(dijit.byId(widgetId),'onBlur', function(){
var sum = 0;
dojo.query('.score')
.forEach(function(ele){
var widgetId = ele.getAttribute('widgetid');
sum += parseInt(dijit.byId(widgetId).get('value'));
});
//***cannot get the value of sum here
dijit.byId('score_total').set('value', sum);
});
}
}
As commented I am unable to get the sum of those values outside the foreach. Is there any way to get the value out of the loop? Am I doing any thing wrong?
It seems that I had made a mistake in the code and since I am quite new to jscript I was unable to debug. foreach indeed is not a asynchronous and sum was being calculated just that the parseInt(dijit.byId(widgetId).get('value')) was returning not a number NaN hence I was unable to populate the form element, I simply added an if condition and it worked
if(parseInt(dijit.byId(widgetId).get('value'))){
sum = sum + parseInt(dijit.byId(widgetId).get('value'));
}
Sorry for the trouble
One thing to note... dojo.foreach is deprecated ...
http://livedocs.dojotoolkit.org/dojo/forEach
instead ... array.forEach
http://livedocs.dojotoolkit.org/dojo/_base/array#forEach
but i think you might also have a scoping issue as well.. try something like this..
var sum = 0;
var elements = dojo.query('.score');
array.forEach(elements, function(ele) {
var widgetId = ele.getAttribute('widgetid');
sum += parseInt(dijit.byId(widgetId).get('value'));
});
in your case, the parent context has the variable, so it will work as you have used it.
Just a side point that if you want to access the sum variable outside the parent context, you will need to use dojo.hitch or pass the context to dojo.forEach
http://www.ibm.com/developerworks/web/library/wa-aj-dojo/
see the section on "Setting method context"

Using jQuery to sum values from a couple text inputs

I have a couple of text inputs and I would like to compute the sum of the values in another input. This must happen on the fly, as soon as the user enters a value in one of the inputs. I'm planning to use jQuery for this, and I would like to add a class name for each input, something like class="input1", class="input2" and so on.
My problem is that I don't know to add all those values, and given the fact that I have over 50 inputs, I don't want to "add them by hand".
Any kind of help is appreciated.
If you decorate all of the inputs you want added together with classes of input1, input2, and so on, this will get the sum of the current values in all those inputs
var sum = 0;
$("input[class *= 'input']").each(function(){
sum += +$(this).val();
});
Then naturally if you want to put this value in an input of id destination
$("#destination").val(sum);
Here's a fiddle
EDIT
If you want this to run whenever any of these textboxes are changed, then you can put this in a change event handler
$(document).on("change", "input[class *= 'input']", function() {
var sum = 0;
$("input[class *= 'input']").each(function(){
sum += +$(this).val();
});
$("#destination").val(sum);
});
Here's that fiddle
EDIT
Per Jaspers comment, if you know that input1, input2, etc, will always be the first class on your inputs, ie, you'll never do
<input class='someNewClass input1'
then you could
$("input[class ^= 'input']").each(function(){
^= means starts with, while *= means contains anywhere.
give them a common name and you need to parse the value since it will be text initially
var result= 0;
$("input[name='sum']").each(function(){
result = result + parseInt($(this).val(),10);
});

Categories