ihtus
ihtus

Reputation: 2811

Numeric validation with RegExp to prevent invalid user input

I have a JavaScript function that validates an input field and prevents the user from typing anything that doesn't match the condition. This function is based on event.keyCode.

I'm trying to modify the function to use a RegExp and validates not "per character" but "per whole input" so that it does the same, but with different conditions:

  1. numeric only
  2. allowed decimal "." or ","

Here is the function in its current form, using event.keyCode:

function isNumeric(evt, alertDIVid, alertMsg) {
    var charCode = (evt.which) ? evt.which : event.keyCode
    if (charCode >= 48 && charCode <= 57) {
        document.getElementById(alertDIVid).innerHTML = '';
        return true;
    }
    else {
        document.getElementById(alertDIVid).innerHTML = alertMsg;
        return false;
    }
}

document.getElementById('AMNT').onkeypress = function(event) {
    event = event || window.event;
    return isNumeric(event, 'numericalert', 'Numeric values only!')
};

Upvotes: 4

Views: 11729

Answers (3)

Peter-Paul van Gemerden
Peter-Paul van Gemerden

Reputation: 7011

In order to do the kind of validation you want, you need to listen to the keyup event instead. This event fires after the field is changed, so that you know the new value of the field. You also need to know the previous value of the field so you can "reset" it if what the user typed turns out to be invalid.

For example:

(function() {
    var previousValue = document.getElementById('myInput').value;
    var pattern = /^\d*((\.|,)\d*)?$/;

    function validateInput(event) {
        event = event || window.event;
        var newValue = event.target.value || '';

        if (newValue.match(pattern)) {
            // Valid input; update previousValue:
            previousValue = newValue;
        } else {
            // Invalid input; reset field value:
            event.target.value = previousValue;
        }
    }

    document.getElementById('myInput').onkeyup = validateInput;
}());

Working demo: http://jsfiddle.net/8kUdG/

It's worth noting that this will also validate empty strings, as well as unfinished numbers, like 5, or 42. (otherwise the user would have to insert the decimal sign after typing the decimals, which would be... weird).

And finally, keep in mind that this might not be a cross-browser safe solution. If you need a pure-JavaScript solution, you will need to refine it (i.e., this might not work in IE).


Edit: of course, showing an error message instead of resetting the input field to the previous value is also perfectly possible (updated JSFiddle):

(function() {
    var pattern = /^(?=.)\d*(?:[.,]\d+)?$/;
    var error = document.getElementById('error');

    document.getElementById('myInput').onkeyup = function(event) {
        event = event || window.event;
        var newValue = event.target.value || '';

        if (newValue.match(pattern)) {
            error.innerHTML = '';
        } else {
            error.innerHTML = 'Not a valid number!';
        }
    };
}());

I leave it up to you to replace the alert with something more user-friendly.

Upvotes: 10

anubhava
anubhava

Reputation: 784898

You can use following regular expression:

/^[+-]?(?=.)(?:\d+,)*\d*(?:\.\d+)?$/

to allow only any number of comma and only one dot . with the condition that number cannot start with a comma. Number can have optional + or - at the start.

Upvotes: 0

Hubro
Hubro

Reputation: 59313

The easiest solution would be something like this

// Returns true on valid, false on invalid
function myInputFilter(input)
{
    var value = input.value;
    var regex = /^[\d\,\.]*$/;

    if(!regex.test(value))
        return false;

    return true;
}

You could edit the function to just take a string argument, but I've chosen to have it accept the text input element instead. The RegEx can be replaced by anything, I've made a simple one for this example. I would refine it a bit if I were you (You can use the excellent online tool RegExr)

Here is an example of the filter implemented

http://jsfiddle.net/kVV77/

Upvotes: 0

Related Questions