Richard
Richard

Reputation: 80

jQuery each loops twice

I am having some trouble with a bit of jQuery.

I have a list of textboxes for inputting numeric values into and a final textbox which would contain the total sum of the other textboxes.

I don't know what I'm doing wrong but each time you enter a number into any of the textboxes the total value is x2 of what the actual value should be. I've tried stepping through the javascript to see whats happening and it looks like the .each is looping twice.

I have spent the best part of 2 days googling this issue and I've not been able to find a solution to my problem.

Here is a link to my code JSFiddle

and here is my javascript

$('.your-income').focusout(function () {
    var tempTotal;

    tempTotal = 0;

    $('.your-income').each(function () {
        tempTotal += Number($(this).val());

        $('#total-income-textbox').val(tempTotal);
    });
});

Thank you for your time.

Upvotes: 3

Views: 6224

Answers (7)

Sadikhasan
Sadikhasan

Reputation: 18600

You have two input in each div set. type=number and type=text that's why it take two time calculate each value. You need to take one of them so I take type=number from them and your problem solved.

 $('.your-income').focusout(function () {
     tempTotal = 0;    
      $('.your-income[type=number]').each(function (index) {
          tempTotal += Number($(this).val());    
      });
          $('#total-income-textbox').val(tempTotal);
  });

Demo

Upvotes: 3

Durgpal Singh
Durgpal Singh

Reputation: 11953

Try This:-

  $('input.your-income').on('focusout', function () 
    {
       var tempTotal = 0;
       $('input.your-income:visible').each(function () 
        {
             tempTotal += parseFloat(this.value, 10);
        });
        $('#total-income-textbox').val(tempTotal);
    }
);

Upvotes: 0

Roamer-1888
Roamer-1888

Reputation: 19288

Once it's fixed, here's two things to improve performance :

  • Convert the jQuery collection of input elements to a proper array then make a running total with Array method .reduce(). No assignemtns required.
  • In reduce's callback, use +el.value, to grab the value and to convert it from String to Number. No need for $(this) in the loop.

Here's the code, based on @Sadikhasan's answer :

$('.your-income').focusout(function () {
    $("#total-income-textbox").val($('.your-income[type=number]').get().reduce(function(sum, el) {
        return sum + +el.value;    
    }, 0));
});

DEMO

Upvotes: 0

Arun Yokesh
Arun Yokesh

Reputation: 1354

  $(document).ready(function () {
     webshims.setOptions('forms-ext', {
         replaceUI: 'auto',
         types: 'number'
     });
     webshims.polyfill('forms forms-ext');
 });
 var tempTotal=0;
 $('.your-income').focusout(function (e) {
         tempTotal += Number($(this).val());
         $('#total-income-textbox').val(tempTotal);
 });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<form>
    <div class="hide-inputbtns">
        <!-- /Household Details -->
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-body">
                    <!-- /Content -->
                    <!-- /Your income -->
                     <h2 class="sub-header">Input Value</h2>

                    <table class="table table-striped table-bordered">
                        <tr class="info">
                            <th class="col-md-2">&nbsp;</th>
                        </tr>
                        <tr>
                            <td class="col-md-2">
                                <div class='input-group'><span class='input-group-addon'>£</span>
                                    <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm your-income' name='your-income' value='0.00' />
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td class="col-md-2">
                                <div class='input-group'><span class='input-group-addon'>£</span>
                                    <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm your-income' name='your-income' value='0.00' />
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td class="col-md-2">
                                <div class='input-group'><span class='input-group-addon'>£</span>
                                    <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm your-income' name='your-income' value='0.00' />
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td class="col-md-2">
                                <div class='input-group'><span class='input-group-addon'>£</span>
                                    <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm your-income' name='your-income' value='0.00' />
                                </div>
                            </td>
                        </tr>
                        <tr>
                            <td class="col-md-2">
                                <div class='input-group'><span class='input-group-addon'>£</span>
                                    <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm your-income' name='your-income' value='0.00' />
                                </div>
                            </td>
                        </tr>
                                                <tr class="info">
                            <td class="col-md-2">
                                <div id="total-income">
                                    <div class='input-group'><span class='input-group-addon'>£</span>
                                        <input type='number' value='0' min='0' step='0.01' data-number-to-fixed='2' data-number-stepfactor='100' class='form-control input-sm' name='total-income' id="total-income-textbox" value='0.00' readonly />
                                    </div>
                                </div>
                            </td>
                        </tr>
                    </table>
                    <!-- Your income/ -->
                    <!-- Content/-->
                </div>
            </div>
        </div>
        <!-- Household Details/ -->
    </div>
</form>

you used the foreach loop in focus out event thats the problem .the code without any console error

Upvotes: 1

user2575725
user2575725

Reputation:

Try this:

  $('input.your-income').on('focusout', function () {
      var tempTotal = 0;
      $('input.your-income:visible').each(function () {
          tempTotal += parseFloat(this.value, 10);
      });
      $('#total-income-textbox').val(tempTotal);
  });

Upvotes: 1

Milind Anantwar
Milind Anantwar

Reputation: 82231

You have two inputs in each set. i.e. type number and type text. you should only use the value from either one of it. you can use :visible selector to target only textboxes as input type number elements has css set to display none:

$('input.your-income:visible').each(function () {
      tempTotal += Number($(this).val());
      $('#total-income-textbox').val(tempTotal);
  });

Working Demo

Upvotes: 1

Pratik Joshi
Pratik Joshi

Reputation: 11693

In each DIV you have 2 classes , 1 for textbox , other for input type number

Check line 3 and 4 below

<div class="input-group">
    <span class="input-group-addon">£</span>
    <input type="number" value="0" min="0" step="0.01" data-number-to-fixed="2" data-number-stepfactor="100" class="form-control input-sm your-income" name="your-income" style="-webkit-appearance: none; display: none;">
    <input class="ws-number ws-inputreplace form-control input-sm your-income wsshadow-1423481433791" type="text" placeholder="" value="0" aria-required="false" inputmode="numeric" aria-labelledby="" style="margin-left: 0px; margin-right: 0px; width: 426.2px;">
    <span class="input-buttons number-input-buttons input-button-size-1 wsshadow-1423481433791"><span unselectable="on" class="step-controls">
    <span class="step-up step-control"></span><span class="step-down step-control"></span></span></span>
</div>

So use $('[name="your-income"]').each(function () {

Working Fiddle

Upvotes: 0

Related Questions