77

I have a text field that allows a user to enter their age. I am trying to do some client-side validation on this field with JavaScript. I have server-side validation already in place. However, I cannot seem to verify that the user enters an actual integer. I am currently trying the following code:

    function IsValidAge(value) {
        if (value.length == 0) {
            return false;
        }

        var intValue = parseInt(value);
        if (intValue == Number.NaN) {
            return false;
        }

        if (intValue <= 0)
        {
            return false;
        }
        return true;
    }

The odd thing is, I have entered individual characters into the textbox like "b" and this method returns true. How do I ensure that the user is only entering an integer?

Thank you

user70192
  • 13,786
  • 51
  • 160
  • 240

11 Answers11

131
var intRegex = /^\d+$/;
if(intRegex.test(someNumber)) {
   alert('I am an int');
   ...
}

That will absolutely, positively fail if the user enters anything other than an nonnegative integer.

karim79
  • 339,989
  • 67
  • 413
  • 406
31

For real int checking, use this:

function isInt(value) { 
    return !isNaN(parseInt(value,10)) && (parseFloat(value,10) == parseInt(value,10)); 
}

The problem with many int checks is that they return 'false' for 1.0, which is a valid integer. This method checks to make sure that the value of float and int parsing are equal, so for #.00 it will return true.

UPDATE:

Two issues have been discussed in the comments I'll add to the answer for future readers:

  • First, when parsing string values that use a comma to indicate the decimal place, this method doesn't work. (Not surprising, how could it? Given "1,001" for example in the US it's an integer while in Germany it isn't.)
  • Second, the behavior of parseFloat and parseInt has changed in certain browsers since this answer was written and vary by browser. ParseInt is more aggressive and will discard letters appearing in a string. This is great for getting a number but not so good for validation.

My recommendation and practice to use a library like Globalize.js to parse numeric values for/from the UI rather than the browser implementation and to use the native calls only for known "programmatically" provided values, such as a string parsed from an XML document.

Paul
  • 6,188
  • 1
  • 41
  • 63
  • @Cesar, as far as I know, there are no programming languages that treat 1,2 as an integer, or as any single numerical value. – ThaMe90 Nov 24 '11 at 07:58
  • @ThaMe90 Thats true, but in my case I was using the isInt function to validate external input. '1,2' is a valid number in some countries where the comma is used as a decimal separator. See: http://en.wikipedia.org/wiki/File:DecimalSeparator.svg – Cesar Canassa Nov 28 '11 at 01:20
  • True, but I'd rather see that as a visual issue rather than a programmatic issue. Nevertheless, I live in such a country myself, so I can think of why you want to do it... – ThaMe90 Nov 28 '11 at 08:29
  • This fails on "09" since parseInt treats it as octal (see: http://stackoverflow.com/questions/8763396/javascript-parseint-with-leading-zeros) – syserr0r Dec 06 '12 at 14:33
  • 2
    `function isInt(value) { return !isNaN(parseInt(value, 10)) && parseInt(value, 10) == parseFloat(value); }` Should work in the above cases. – syserr0r Dec 06 '12 at 14:44
  • New browsers have dropped the auto-octal behavior, however it seems that these methods are also more tolerant than previous implementations. I haven't got an older browser to test, but at least on the latest Chrome release parseInt('1a') returns 1. I don't remember this working on say IE7... As an aside, I usually use a library like Globalize.js if the behavior of client-side of numeric data handling is important to me. – Paul Dec 06 '12 at 19:06
  • 3
    DON'T USE THIS ALGORITHM! It will tell you that `isInt('5a') == true`! – machineghost Apr 03 '13 at 00:28
  • Thanks @machineghost for repeating my last comment IN ALL CAPS, but this isn't an algorithm (http://en.wikipedia.org/wiki/Algorithm), it's a boolean logical test utilizing libraries built into the environment. The behavior is determined by the specific implementations of the parseInt and parseFloat algorithms that you use. – Paul Apr 03 '13 at 12:51
  • First off, I'll admit that algorithm was the wrong term (I was being lazy in my terminology). And generally speaking I consider "speaking" in all caps to be rude also. However, given that my comment is "below the fold", and since this seems like a pretty major flaw (and this is the 2nd highest rated answer), I wanted to do what I could to make it visible. As for it being "determined by the specific implementations", if any of those implementations are major browsers then that's all that matters to most web developers: if Chrome does it but IE and Firefox don't you still can't use it. – machineghost Apr 03 '13 at 15:29
  • Well, I'll update the answer so it's clear to anyone who looks at it. – Paul Apr 03 '13 at 17:54
  • 1
    I've used almost the same method, adding a test on the `toString` method of both the original value and the transformed value : `var isint = function (a) { return ((parseInt(a) === parseFloat(a)) && (a.toString() === parseInt(a).toString())); }` – Ghislain Leveque Jun 18 '14 at 08:07
  • For simpler... `function validateInt(i) { var j = parseInt(i); return !isNaN(j) && i.toString() === j.toString(); }` – mpyw Oct 02 '14 at 15:16
13

use isNaN(n)

i.e.

if(isNaN(intValue))

in place of

if (intValue == Number.NaN)
Jumipo
  • 246
  • 1
  • 3
  • 1
    isNaN() means is Not a Number and returns false if it is a number. Just got me confused :) – broch Aug 27 '13 at 14:48
8

UPDATE

I have fixed the code that had an error and added a var called key to store the key pressed code using keyCode and which, that depend of the browser.

var key = e.which || e.keyCode;

Thanks Donald.McLean :)


If you want to check if you are writing numbers while typing (and avoid writing other characters into your input field), you can use this simple function and you can define the elements allowed (this include whatever you want to filter). In this way you can choose not only integers but for example a certain group of characters. The example is based in jQuery to attach it to an input field.

$('#myInputField').keypress(function(e)
{
    var key = e.which || e.keyCode;

    if (!(key >= 48 && key <= 57) && // Interval of values (0-9)
         (key !== 8) &&              // Backspace
         (key !== 9) &&              // Horizontal tab
         (key !== 37) &&             // Percentage
         (key !== 39) &&             // Single quotes (')
         (key !== 46))               // Dot
    {
        e.preventDefault();
        return false;
    }
});

If you use other key than the defined, it won't appear into the field. And because Angular.js is getting strong these days. this is the directive you can create to do this in any field in your web app:

myApp.directive('integer', function()
{
    return function (scope, element, attrs)
    {
        element.bind('keydown', function(e)
        {
            var key = e.which || e.keyCode;

            if (!(key >= 48 && key <= 57) && // Interval (0-9)
                 (key !== 8) &&              // Backspace
                 (key !== 9) &&              // Horizontal tab
                 (key !== 37) &&             // Percentage
                 (key !== 39) &&             // Single quotes (')
                 (key !== 46))               // Dot
            {
                e.preventDefault();
                return false;
            }
        });
    }
});

But what happens if you want to use ng-repeat and you need to apply this directive only in a certain number of fields. Well, you can transform the upper directive into one prepared to admit a true or false value in order to be able to decide which field will be affected by it.

myApp.directive('rsInteger', function() {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            if (attrs.rsInteger === 'true') {
                element.bind('keydown', function(e)
                {
                    var key = e.which || e.keyCode;

                    if (!(key >= 48 && key <= 57) && // Interval (0-9)
                         (key !== 8) &&              // Backspace
                         (key !== 9) &&              // Horizontal tab
                         (key !== 37) &&             // Percentage
                         (key !== 39) &&             // Single quotes (')
                         (key !== 46))               // Dot
                    {
                        e.preventDefault();
                        return false;
                    }
                });
            }
        }
    }
});

To use this new directive you just need to do it in a input type text like this, for example:

<input type="text" rs-integer="true">

Hope it helps you.

Timbergus
  • 3,167
  • 2
  • 36
  • 35
  • Thanks Donald.McLean, but is not for the keys but for the browser: keyCode and watch as I have found here (http://stackoverflow.com/questions/4471582/javascript-keycode-vs-which), depends on the browser. – Timbergus Feb 20 '14 at 10:23
4

I did this to check for number and integer value

if(isNaN(field_value * 1) || (field_value % 1) != 0 ) not integer;
else integer;

Modular Divison

Example
1. 25.5 % 1 != 0 and ,
2. 25 % 1 == 0

And if(field_value * 1) NaN if string eg: 25,34 or abcd etc ... else integer or number

Kshitiz
  • 2,673
  • 1
  • 18
  • 24
2

function isInt(x) {return Math.floor(x) === x;}

Kariudo
  • 534
  • 5
  • 10
1

If your number is in the 32bit integer range, you could go with something like:

function isInt(x) { return ""+(x|0)==""+x; }

The bitwise or operator forces conversion to signed 32bit int. The string conversion on both sides ensures that true/false want be matched.

Vajk Hermecz
  • 5,413
  • 2
  • 34
  • 25
1

Nobody tried this simple thing?

function isInt(value) {
    return value == parseInt(value, 10);
}

What's wrong with that?

  • While it's phrased as a question, this is an answer to the question. Unless there is some subtlety I'm missing, it even is a correct answer to the question. – Foon Jun 07 '15 at 12:31
  • parseInt('5HowdyDoody0',10) returns 5. That makes it unsuitable for validation. – david wendelken Sep 27 '17 at 14:50
0

You may use isInteger() method of Number object

if ( (new Number(x)).isInteger() ) {
  // handle integer
}

This method works properly if x is undefined or null. But it has poor browser support for now

Sneg
  • 1,039
  • 1
  • 11
  • 15
0

I found the NaN responses lacking because they don't pick up on trailing characters (so "123abc" is considered a valid number) so I tried converting the string to an integer and back to a string, and ensuring it matched the original after conversion:

if ("" + parseInt(stringVal, 10) == stringVal) { alert("is valid number"); }

This worked for me, up until the numbers were so large they started appearing as scientific notation during the conversion.

...so of course this means you could enter a number in scientific notation, but checking minimum and maximum values as well would prevent that if you so desire.

It will of course fail if you use separators (like "1,000" or "1.000" depending on your locale) - digits only allowed here.

Malvineous
  • 25,144
  • 16
  • 116
  • 151
-4
If (enteredAge < "1" || enteredAge > "130") ......

Simple and it works....until they develop immortality

Zardiw
  • 11
  • 10