GCW
GCW

Reputation: 312

jQuery - sum every input value in a form

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

Answers (6)

TheZanke
TheZanke

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

brk
brk

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);
});

JSFIDDLE

Upvotes: 1

Praveen
Praveen

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

Rayon
Rayon

Reputation: 36609

Define the variable locally or else global value will be updated every time change 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>

Updated Fiddle

Upvotes: 2

asdf_enel_hak
asdf_enel_hak

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

eisbehr
eisbehr

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

Related Questions