Reputation: 312
I'd like to count the sum of all the numeric values of a lot of input fields inside a form, every time one of the values changes. I think this code is quite closer, but when I change twice the same input it is wrong.
tot = 0;
$('form#form-id :input').change(function(){
$("form#form-id :input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
});
This also seems to works well on jsFiddle https://jsfiddle.net/yq9zenaz/ but I get NaN on production.
Upvotes: 0
Views: 4535
Reputation: 1078
Here's an alternate solution:
What we do is get the jQuery collection of all inputs, use .map()
to create a jQuery collection of input values, use .get
to get the array from the jQuery object. After all of that we run .reduce
with an add function on the array to get the sum of all values.
var $inputs = $("form#lines-form-1 :input");
$inputs.change(function() {
var tot = $inputs
.map(function() {
return Number(this.value);
})
.get()
.reduce(function(a, b) {
return a + b;
});
console.log(tot);
$('#tot-qty').text(tot);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="lines-form-1">
<input type="number" name="i1"><br>
<input type="number" name="i2"><br>
<input type="number" name="i3"><br>
<input type="number" name="i4"><br>
<input type="number" name="i5"><br>
</form>
<div id="tot-qty">0</div>
And if you want tot
to be in the parent scope, you can move it's declaration to outside the .change
event and it'll still work since it's being completely reassigned instead of added to.
Upvotes: 1
Reputation: 50291
Declare tot
variable inside change
and declare it with variable keyword
$('form#lines-form-1 :input').change(function(){
var tot = 0;
$("form#lines-form-1 :input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
$('#tot-qty').text(tot);
});
Upvotes: 1
Reputation: 657
You should initialise variable tot within change handler.
$('form#lines-form-1 :input').change(function(){
tot = 0;
$("form#lines-form-1 :input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
$('#tot-qty').text(tot);
});
Upvotes: 1
Reputation: 36609
Define the variable locally or else
global
value will be updated every timechange
handler is invoked.
$('form#lines-form-1 :input').change(function() {
var tot = 0;
$("form#lines-form-1 :input").each(function() {
tot += Number($(this).val());
// Could be written as
// tot += +this.value;
});
$('#tot-qty').text(tot);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form id="lines-form-1">
<input type="number" name="i1">
<br>
<input type="number" name="i2">
<br>
<input type="number" name="i3">
<br>
<input type="number" name="i4">
<br>
<input type="number" name="i5">
<br>
</form>
<div id="tot-qty">0</div>
Upvotes: 2
Reputation: 7640
You need to reset tot to zero each time
tot = 0;
$('input').change(function(){
tot = 0;
$("input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input/>
<input/>
Upvotes: 1
Reputation: 12452
Reset tot
inside the callback, otherwise you will be continue adding numbers, but it's not the correct value.
Updated your fiddle: https://jsfiddle.net/yq9zenaz/1/
var tot = 0;
$('form#lines-form-1 :input').change(function(){
tot = 0;
$("form#lines-form-1 :input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
$('#tot-qty').text(tot);
});
If you don't need tot
to be accessible globally, just use it on the inside only:
$('form#lines-form-1 :input').change(function(){
var tot = 0;
$("form#lines-form-1 :input").each(function(){
tot += Number($(this).val());
});
console.log(tot);
$('#tot-qty').text(tot);
});
Upvotes: 1