0

I am trying to get the value from a bunch of input text fields on a form, then check whether or not they add up to 100. I am using the below jQuery to do this, though I just get "NaN" returned - anyone know why this is? No Doubt something stupid I've missed(!)

var formPercentageTotal = 0;
var currentVal = 0;
setInterval(function(){
    $('.percentage-validate input.three-digit').each(function(){
        currentVal = $(this).val();
        currentVal = parseInt(currentVal);
        formPercentageTotal = formPercentageTotal + currentVal;
    });
    $('.percentage-validate .percentage-current').text(currentVal);
}, 500);

JSFiddle

4
  • 4
    Interesting, a fiddle will help Commented Jul 3, 2014 at 8:32
  • 1
    I suspect that you are trying to use parseInt on a value that is not a number - try to inspect each value in each iteration and validate that you are indeed dealing with numerical values. Commented Jul 3, 2014 at 8:34
  • @Hanky웃Panky Fiddle added Commented Jul 3, 2014 at 8:41
  • That makes it obvious, you get NaN only when any field is empty, that means you are not checking whether a number is there before adding it. When all your textboxes have proper numbers the result is good. Rest you can solve yourself cause you can program good :) Commented Jul 3, 2014 at 8:43

2 Answers 2

3

Try checking for NaN before adding up. You might have entered a alpahabet in any of the input field. Fiddle

Edit: You should set formPercentageTotal into .formPercentageTotal.

var formPercentageTotal = 0;
var currentVal = 0;
setInterval(function(){
    $('.percentage-validate input.three-digit').each(function(){
        currentVal = $(this).val();
        currentVal = parseInt(currentVal);
        if (!isNaN(currentVal)) {
           formPercentageTotal = formPercentageTotal + currentVal;
        }
    });
    $('.percentage-validate .percentage-current').text(formPercentageTotal);
}, 500);
Sign up to request clarification or add additional context in comments.

6 Comments

Still getting the same result (NaN). I am completing the input fields myself, and am only entering numbers
Can you setup a fiddle?
@wickywills better provide fiddle
Fiddle added - please see original post
Close, but in your fiddle, the total value keeps going up on every timer interval even if I only enter a single value in one field
|
1

The question is already answered, but there are some things about your code, that make it inefficient and quite error-prone. Consider this piece of code:

$.fn.boundForm = function(options) {

    var defaults = {
        fields: ".three-digit",
        total: ".percentage-current",
        validateInput: function(item) {
            item.value = parseInt(item.value.replace(/[^0-9]+/g, "")) || 0;
            return parseInt(item.value);
        },
        calculateTotal: function(fields) {            
            return fields.toArray().reduce(function(sum, item) {
                return sum + this.validateInput(item);
            }.bind(this), 0);
        },
        refresh: function(form) {
            form.find(this.total).text(this.calculateTotal(form.find(this.fields)));
        }
    }


    var o = $.extend({}, defaults, options);

    this.each(function() {
        var $form = $(this);    
        $form.on("input", o.fields, function() {
           o.refresh($form);
        });

        o.refresh($form);
    });
};

$(".percentage-validate").boundForm();

This is a basic widget, that does the same thing as your code, but:

  1. It includes validation method validateInput, that replaces any non-numbers, and return 0 if value is empty;
  2. It doesn't require 'dirty checking' every time interval to determine if value has changed, so it is more efficient;
  3. It is reusable - if you need to calculate some other values elsewhere - you can easily do so just by passing an object containing different selectors, methods, and whatever, and it would still work just fine, and you'd need to simply call $("#myContainer").boundForm(myOptions);

All in all, that makes for much more convenient code to work with. Hope that helps.

P. S. Here's fiddle

1 Comment

Thanks very much for this, much better way to do it! I'm actually already now forcing only numbers to be in the input field using something similar to the regex in your code. I think I might get rid of my setInterval though as you suggest. Much better way. +1 :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.