0

I have a function that checks if a user writes a digit in an input box:

var letters = 'ABCÇDEFGHIJKLMNÑOPQRSTUVWXYZabcçdefghijklmnñopqrstuvwxyzàáÀÁéèÈÉíìÍÌïÏóòÓÒúùÚÙüÜ';
var numbers = '1234567890';
var signs = ',.:;@-\'';
var mathsigns = '+-=()*/';
var custom = '<>#$%&?¿';


function alpha(event) {
    var k;
    k = document.all ? parseInt(event.keyCode) : parseInt(event.which);
    return (numbers.indexOf(String.fromCharCode(k)) != -1);
}

This function is used together with the following function, that takes the digit and sends it to a controller, which saves the digit in the database. But only if the digit is different from the original digit, that was in the input box in the first place. It also updates another input box, with the sum off all specific input that have the same row_id attribute as the input box which fired the event:

function initializeUpdateNumberProcentMatrix() {

    $(".numberfield").live('keypress', alpha);

    //$(".numberfield").live('keypress', alpha(numbers));


        $('.numberfield').live('focus', function () {
            $(this).attr('oldvalue', $(this).val());
        });

        $('.numberfield').live('blur', function () {

            // Dette er den nuværende værdi i tekstboksen
            var value = $(this).val();
            var oldvalue = $(this).attr('oldvalue');

            // Reference til tekstboksen
            var obj = $(this);

            // Hvis værdien ikke har ændret sig, skal der ikke foretages noget (hvis man tabulerer)
            if (value == $(this).attr('oldvalue')) {
                return;
            }

            else {

                var dif = value - $(this).attr('oldvalue');
                var newval;


                $('.procentsumfield').each(function (index) {
                    if ($(this).attr('row-id') == obj.attr('row-id')) {

                        newval = (parseInt($(this).val()) + parseInt(dif));

                        // Hvis summen overstige 100, skal der ikke foretages nogle ændringer - Textboksens værdi skal tilbagestilles, og sumfeltet skal ikke odateres                
                        if (newval > 100) {
                            obj.val(oldvalue);
                            alert("Summen for det pågældende år må ikke overstige 100%");
                            return;
                        }
                        else {
                            $(this).val(newval);
                            return false;
                        }
                    }
                });

                var number = { Column_ID: $(this).attr('column-id'),
                    Row_ID: $(this).attr('row-id'),
                    Question_ID: $(this).attr('question-id'),
                    Value: $(this).val(),
                    Type: "Procent"
                };

                // Hvis den nye værdi overstiger 100, skal det ikke gemmes
                if (newval <= 100) {
                    saveNumberMatrix($(this), number, "/SaveSurveyAnswers/SaveProcentMatrix");
                }
            }
        });
    }

The problem is, that sometimes IE 7 gives me a NaN in the "procentsumfield" input box, and it doesnt save the new value because it's not a number.

What could cause this to happen?

Thanks

Andrew Leach
  • 12,945
  • 1
  • 40
  • 47
Kenci
  • 4,794
  • 15
  • 64
  • 108
  • 1
    In jQuery [`event.which`](http://api.jquery.com/category/events/event-object/) is normalized (and should be an int) – gen_Eric May 15 '12 at 16:50
  • 1
    FYI: `document.all` check is bad. – epascarello May 15 '12 at 16:50
  • 1
    A recommendation: don't use live(); it is deprecated, use on(); – Oscar Jara May 15 '12 at 16:50
  • 1
    FYI: When using `parseInt`, you should pass `10` as the 2nd parameter. That makes sure the numbers are read as "base 10". If you did `parseInt('021')` this would return `17`, not `21` as it's interpreted as "base 8" (the starting `0` makes it "octal"). `parseInt('021', 10)` would return `21`. – gen_Eric May 15 '12 at 16:52

2 Answers2

2

NaN is viral/poison. If a value is NaN then (pretty much) any other values that went into its calculation could be the cause. In this case:

  • parseInt($(this).val()) might be returning NaN
  • parseInt(dif) might be returning NaN, potentially caused by
    • value being NaN, or
    • $(this).attr('oldvalue') returning something that cannot be coerced to a number
  • etc.

(Side comment: why are you parseInt()ing dif? It's already a number, or NaN. Also, even if it were a string, it's silly to parseInt() it inside of the loop.)

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • You are right. When i loop over the input boxes, and if some of them are empty, no value, they become NaN when parsed. – Kenci May 15 '12 at 18:02
0
var dif = value - $(this).attr('oldvalue');

Both value and $(this).attr('oldvalue') are strings. - only works on ints, so string-string is NaN.

You need to use parseInt on these.

var value = parseInt($(this).val(), 10);
var oldvalue = parseInt($(this).attr('oldvalue'), 10);

Note the ,10, this makes sure the values are "base 10".

EDIT: As stated in the comments, the NaN is coming from $(this).val() being empty (''). You can check for that like so:

if($.trim($(this).val()) === '')

Or:

var value = parseInt($(this).val(), 10);
if(isNaN(value))

You set oldvalue but you never use it, you should use it instead of getting the attribute each time.

var dif = value - oldvalue;

Also change this line newval = (parseInt($(this).val()) + parseInt(dif)); to:

newval = parseInt($(this).val(), 10) + dif;

dif is already an int, no need for parseInt.

Another note: In jQuery event.which is normalized (and should be an int), so you don't need to "check" for it.

function alpha(event) {
    return (numbers.indexOf(String.fromCharCode(event.which)) != -1);
}
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • _"`-` only works on ints, so `string-string` is `NaN`."_ Not always true. Try `'123' - '456'` – Matt Ball May 15 '12 at 17:10
  • Thank you for the answer. I will make all the corrections. I found out that when onblur fires, and there are input boxes which are empty (no value), they are NaN in the loop. How can i fix this? – Kenci May 15 '12 at 18:00
  • @Kenci: Empty values! Yeah, that's it! `parseInt('', 10)` is `NaN`. You can either check `if($(this).val() == '')` or `isNaN(value)`. – gen_Eric May 15 '12 at 18:02
  • 1
    @Kenci instead of using `parseInt()`, you can actually use unary `+`, which handles the empty string more gracefully. Ex.: `+'' = 0`; `+'123' = 123`; `+'abc' = NaN`. More reading: http://stackoverflow.com/questions/4090518/string-to-int-use-parseint-or-number – Matt Ball May 15 '12 at 19:29