Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!')
};
like image 252
ihtus Avatar asked Jan 18 '23 19:01

ihtus


1 Answers

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.

like image 109
Peter-Paul van Gemerden Avatar answered Jan 31 '23 09:01

Peter-Paul van Gemerden