Basic Javascript Data Validation

Data validation is the process of ensuring that data (Normally entered into a form of some kind) is in the same format as you want and expect it to be in.
For example, if you ask someone to type in their birth month and you want them to use the textual label for the month rather than the numerical representation (i.e "February" rather than "2" or "02") then using datavalidation you should test that the end user is typing in the textual label for the month.

All this is of course they're even attempting to type the correct information into the form, sometimes people will intentionally type in malicious code into your forms with the intent of deleting all information from your database, or worse, stealing it for themselves, which would be catastrophic if this were to happen to a bank for example.

Although data validation is the answer, you shouldn't just do it on the client side (i.e. with javascript) as the second somone turns off javascript in their browser, you're back to square 1 in terms of security.
All data should be validated on the server side as it can't be circumvented by the end user, however you may want to make your applications and forms more responsive by allowing people to see validation as they're typing in, rather than having to wait until they've submitted the form to see the results.

If you were only to use server side data validation the user would have to submit the form before they were able to see any error messages, however if you also use javascript, users can see if they're typing in invalid data as they're filling out the form, down to each individual key depression if you like.

Lets have a look at how to validate a basic date, we'll use 23/09/1990 as an example.

First we need to establish that this is in the format of DD/MM/YYYY, so the above is 23rd September 1990. By looking at the above example this may beem obvious, but I want you to look beyond the obvious as it will help you to write better code.

For the sake of simplicity we'll pretend that the user will always put a zero at the beginning onf a single digit date element (Day or Month).
Overall the date will be 10 characters long, composed of 2 characters for the day, 2 characters for the month and 4 characters for the year, all separated by 2 forward slashes.

Here's what we've got as a starting point:

var myDate = '23/09/1990';
var myDatePattern = /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/;
alert(myDatePattern.test(myDate));

Firstly we create a variable to store our date and populate it with the date we decided upon earlier. This is just for the purposes of testing, in a real life scenario you probably wont know what the date will be ahead of time (If you did, there would be little point in validating the data on the client side).
Later on we'll hook this up to a text field and a button so you can try typing in whatever you want without having to change the javascript manually.

Next we create a variable that contains our pattern to match the dates against (Which will require the most explanation).
What we've created is an instance of the RegExp object (Regular Expression) using literal syntax.

Everything between the two forward slashes is the pattern we want to match data against.
The square brackets ( [ ] ) denote groups, we've used 0-9 for each group as we only want numbers (Any numbers between 0 and 9 for now).
At the end of each group we've put a number in curley brackets ( { } ), this denotes the number of times the previous item is allowed to appear for that group, so "[0-9]{2}" means match any 2 numbers between 0 and 9.

Either side of the middle group (The Month) you'll see "\/" which looks like a "v" but it's actually a backslash ( \ ) followed by a forward slash ( / ). We know what the forward slash is for as we're using it to separate each date element from eachother. The backslash is used to "escape" special characters, this means to allow the characters to appear as they actually are rather than perform their special function.
The special function of the forward slash in the context of our pattern is to signify the beginning or end of the pattern, so if we just put the forward slashes in without escaping them, our pattern would end prematurely matching only a day (Though technically it wouldn't work at all as it's invalid javascipt).
What we're saying is "I want to put forward slashes in as textual items only".

Finally if you look at the beginning and end of the pattern you'll see ^ and $, this means beginning with and end with. In the context of our pattern we've said the pattern begins and ends with a number.

On the last line we're just echoing out whether or not "myDate" passed the pattern matching successfully, this follows the syntax of pattern.test(variable to test the pattern against).(test is a method of the RegExp object).

Improving The Pattern

You might think we're done, not quite. Although the pattern works, it's not bullet proof (Or idiot proof to be more precise).
If you remember earlier, we said that the date is in the format of DD/MM/YYYY.
See what happens if you try 23/99/1990 as the value of myDate. It passes the validation, which is not correct, not only that, but you can also specify up to 99 as the day as well, both of these need correcting.

var myDatePattern = /^[0-3]{1}[0-9]{1}\/[0|1]{1}[0-9]{1}\/[0-9]{4}$/;

Now we're getting somewhere.
We're saying that the day can begin with a 0,1,2 or 3 but nothing else, we've also said that the second digit of the day element and still be any number, both parts of the day must still be 2 digits in length combined.

What we've done next for the month element of the date is a little different.
[0|1]{1} Means that the first digit of the month element can be 0 OR 1 and must be only 1 character long and the second character can be any single digit number.
We've left the year part of the pattern untouched for now.

Improving The Pattern Further

Although the pattern is better, it's still not bullet proof.
An end user can still specify 32nd day of the 13th Month 1990, of course there is no more than 31 days in a month and no more than 12 months in a year.
Making this completely bullet proof, ie.e taking into account leap years and the true number of days in a specific month (February for example) is beyond the scope of this article (Though I'll likely revist that aspect in a future article).

If we want to more effectively use this pattern, we need to chop the input up into pieces with the following code:

alert(myDate.substring(0,2));

As you can probably tell by now, I like to alert out the result of all of my work as I go along so that I can see that it's all working properly. Even for simple tasks like this it's useful, but it will really shine through when we start doing more complicated work.

What we've done is use the substring method, it follows the syntax of:
OjectYouWantASubstringOf.substring(start position, stop position)

So we're saying "look at the myDate variable and return all characters between the 1st and 2nd character", which is just the day, we can do the same with the month and year, not only that but we'll want to store them in variables for further testing and manipulation:

var myDay = myDate.substring(0,2);
var myMonth = myDate.substring(3,5);
var myYear = myDate.substring(6,10);

Now we're not going to completely abandon our previous regular expression that we've created, as it's still useful to us.

The next thing to do is limit the values for these variables.

if(myDay > 31 | myDay < 1){
    alert('You have entered an invalid day');
}

if(myMonth > 12 | myMonth < 1){
    alert('You have entered an invalid month');
}

var now = new Date();
if(myYear > now){
    alert('You have entered an invalid year. Please use a date before today');
}

We've stated that the day can be no more than 31 and no less than 1, the month can be no more than 12 and no less than 1 and the year must be before today's date.
We've also placed alerts for each date element so that the user will be alerted to which specific part of the date is invalid.

Now if you wanted to you could include the following code in a function to check that all of the date elements are valid.
This is probably overkill for the client side, but you'd certainly want to do it on the server side.

if(day==false | month==false | year==false){
    validDate=false
}
else{
    validDate=true
};
alert(validDate);

All that's left to do now is to tie all of our code into a form with a button to validate whatever the end user types in.
Prepare yourself for a big chunk of code:

HTML:

<form id="form1" name="form1" method="post" action="">
    <label>Date
        <input name="myDate" type="text" id="myDate" value="" />
    </label>
    <input name="Submit" type="button" value="Submit" onClick="validDate()"/>
</form>

Javascript

<script type="text/javascript">
    function validDate() {

        var myDate = document.getElementById('myDate').value;
        var myDatePattern = /^[0-3]{1}[0-9]{1}\/[0|1]{1}[0-9]{1}\/[0-9]{4}$/;
        var validFormat = myDatePattern.test(myDate);

        if (validFormat == true) {

            var myDay = myDate.substring(0, 2);
            var myMonth = myDate.substring(3, 5);
            var myYear = myDate.substring(6, 10);

            if (myDay > 31 | myDay < 1) {
                alert('You have entered an invalid day');
                var day = false;
            }
            else {
                var day = true
            };

            if (myMonth > 12 | myMonth < 1) {
                alert('You have entered an invalid month');
                var month = false;
            }
            else {
                var month = true
            };

            var now = new Date();
            if (myYear > now) {
                alert('You have entered an invalid year. Please use a date before today');
                var year = false;
            }
            else {
                var year = true
            };

            if (day == false | month == false | year == false) {
                var validDate = 'invalid'
            }
            else {
                var validDate = 'valid'
            };
            alert('The date you have entered is ' + validDate);
            return validDate;
        }

        else {
            alert('You have entered an invalid date format');
        };

    }
</script>

First we've created a form with a text input with an id of "myDate".
Then we've attached a function called "validDate()" to the submit button. If you try typing in a correctly formatted date, it will tell you so, it will also alert you if you've made a mistake.
We've wrapped all of the code inside this function to prevent variable name collisions with other javascript code you may have written (More on this and why it's important in a seperate article).

With the line "var myDate = document.getElementById('myDate').value;" we're storing the value of the value of the text input in a variable for later use.
We then wrap everything in an if statement to prevent unnecessary code from being run and tested, if the date format is valid, it tests to make sure that each individual component isn't outside of the ranges that we've specified.
If the date format is not valid then the user simply gets an invalid date format error and none of the other validation is done.

Below is a working example of what we've done:



 

We've done quite a bit of validation on this data, it's still not perfect, but we'll cover that in another article, for now you've seen quite a lot of validation, possibly more than you may have thought necessary.
How far you want to take your validation is entirely up to you.
As long as you're not repeating yourself, it's normally a case of "more is better".

In a future article I'll show you how we can take this code and insert validation messages within the html document for the user to see, rather than using alert boxes.

If you enjoyed this article, please consider giving it a +1

Tags: javascript, validation

Published: 5/12/2014 7:52:36 PM
By: Stephen Warren