Client side form validation with JavaScript that even works in IE8

June 8th, 2012

I’m a big fan of client side validation because, a) I’m a front-end guy and b) since I use Ajax to send the content to the server, I don’t really want to go to the trouble of checking it on the server and sending it back. Up until recently, I used jQuery to validate the content of a form but one day I noticed on a couple of sites I’d built that I was only using jQuery on the contact page. As great as jQuery is, I wondered if I really need to load all that extra code to make sure a couple of inputs weren’t empty when a visitor pressed a submit button.

Here’s an example of how I used to write some validation code with jQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var submit = $(‘submit’);
var name = $(‘#name’);
var email = $(‘#email’);
var dataString = ‘’;

submit.on(‘click’, function(e) {
    e,preventDefault();
    if (name.val() === ‘’) {
        name.val(‘Required’);
    }
    if (email.val() === ‘’) {
        email.val(‘Required’);
    }
    dataString =name=+ name +&email=+ email;
}

For every input or textarea in the form that had to be filled out, I’d create a new variable and check if its value was empty or not. This isn’t a big deal when you only have a couple of inputs to check, but the bigger the form, the more unwieldy it becomes. Over time I refined how I did this, using a couple of for loops to check inputs and to create the string variable, called dataString in my example, which I would send to whatever php file I was using. Then I took a look at the code realized I was using jQuery for two things, to select things in the DOM and to use Ajax to send to the information to my php mailing file. So I set about trying to write it in vanilla JavaScript, mainly to see if I could and also, if I could get it to work, I wouldn’t need to load jQuery and that would make things run faster. I decided to make sure it worked as far back as Internet Explorer 8. If you run the code in IE7, it just works like a regular form and goes to the php file, which isn’t that big of a deal. And if you just have to have it work the same in IE7, then use jQuery.

First our HTML:

1
2
3
4
5
6
7
8
9
<div class="wrapper">
    <form id="form" method="get" action="test.php">
        <p><label for="name">Name: </label><input class="required" type="text" name="name"></p>
        <p><label for="email">Email: </label><input class="required" type="email" name="email"></p>
        <p><label for="company">Company: </label><input type="text" name="company"></p>
        <p><label for="comments">Comments: </label><textarea name="comments"></textarea></p>
        <p><button type="submit">Submit</button></p>
    </form>
</div>

Just a simple, run of the mill contact form. You’ll notice that the name and email inputs have a class of required. For this example, we’re going to set it up so that the user must enter their name, email and a comment but not a company because not everyone owns a company. Now on to our JavaScript. First off, our variables:

1
2
3
4
5
6
7
8
9
(function() {
    var wrapper = document.querySelector('.wrapper');
    var btn = document.querySelector('button');
    var inputs = document.querySelectorAll('input');
    var required = document.querySelectorAll('input.required');
    var textarea = document.querySelector('textarea');
    var ajaxRequest = new XMLHttpRequest();

})();

If you’ve never seen them before, querySelector selects the first item in the DOM it finds that matches what you pass to it, and querySelector all selects all the items that match what you pass to it. So if you’re just selecting something that there’s only one of, like the div with the class of wrapper, then you use querySelector. To grab all of our inputs, we use querySelectorAll. Everything here should be pretty self-explanatory, but you might be wondering why we’re selecting all the inputs and then the inputs with a class of required. We’ll check the required inputs in a loop and create the string we need to pass using Ajax using all the inputs.

Next, add this (all the code goes inside the anonymous function):

1
2
3
4
5
if (btn.addEventListener) {
    btn.addEventListener('click', validateForm, false);
} else if (btn.attachEvent) {
    btn.attachEvent('onclick', validateForm);
}

Since we want this to work in IE8, we have to write our click event a bit different. If you’ve been working with JavaScript for a while you’ve seen this before but if you haven’t, here’s what’s happening. Versions of IE before 9 use attachEvent instead of addEventListener. It’s one of those wonderful things Microsoft did to make our lives easier. But it’s pretty simple to get around, we just check if addEventListener exists and if it does, add it to our button, if it doesn’t and attachEvent does, then add that to our button.

When the button is clicked, we call a function called validateForm.

1
2
3
4
function validateForm(e) {
    var dataString = '';
    e.preventDefault ? e.preventDefault() : e.returnValue = false;
}

First, we create variable called dataString that equals an empty string and then we have a line of code that might look weird. You’ve probably seen e.preventDefault() before, it prevents our button from submitting the form, but it doesn’t work in IE8. We need to use e.returnValue = false instead, so, just like with the event listener, we check if preventDefault exists and if it does, we use it and if it doesn’t we use the IE8 version. Now we’ll add the loop we’ll use to check the value of the inputs with the class of required.

1
2
3
4
5
6
7
8
9
10
11
12
function validateForm(e) {
    var dataString = '';
    e.preventDefault ? e.preventDefault() : e.returnValue = false;

    for (var i = 0; i < required.length; i++) {
        var value = required[i].value;
        if (value === '' || value === 'Required') {
            required[i].value = 'Required';
            return false;
        }
    }
}

This is really simple. we just loop through all the items in our p object and check if their value is empty or if it’s ‘Required’. Why are we checking both? Well, if it’s empty, we want to set the value to required so that the visitor knows they need to fill out that input field. If we just check to see if the input has an empty value, then it will let the user submit the form if the value is ‘Required’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function validateForm(e) {
    var dataString = '';
    e.preventDefault ? e.preventDefault() : e.returnValue = false;

    for (var i = 0; i < required.length; i++) {
        var value = required[i].value;
        if (value === '' || value === 'Required') {
            required[i].value = 'Required';
            return false;
        }
    }
    if (textarea.value === '' || textarea.value === 'Required') {
        textarea.value = 'Required';
    }
}

Next, we add an if statement to check our textarea. If you had more than one textarea in your form, you could run a loop or combine it with your other loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function validateForm(e) {
    var dataString = '';
    e.preventDefault ? e.preventDefault() : e.returnValue = false;

    for (var i = 0; i < required.length; i++) {
        var value = required[i].value;
        if (value === '' || value === 'Required') {
            required[i].value = 'Required';
            return false;
        }
    }
    if (textarea.value === '' || textarea.value === 'Required') {
        textarea.value = 'Required';
    }

    for (var i = 0; i < inputs.length; i++) {
        dataString += inputs[i].name + '=' + inputs[i].value + '&';
    }
    dataString += textarea.name + '=' + textarea.value;
}

Now we use another for loop to create the string that we’ll pass to our PHP file. After the loop, we add the textarea content to dataString. If you logged dataString, you’d get something like this: ‘name=Name&email=email@mail.com&company=Company&comments=A comment!’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function validateForm(e) {
    var dataString = '';
    e.preventDefault ? e.preventDefault() : e.returnValue = false;

    for (var i = 0; i < required.length; i++) {
        var value = required[i].value;
        if (value === '' || value === 'Required') {
            required[i].value = 'Required';
            return false;
        }
    }
    if (textarea.value === '' || textarea.value === 'Required') {
        textarea.value = 'Required';
    }

    for (var i = 0; i < inputs.length; i++) {
        dataString += inputs[i].name + '=' + inputs[i].value + '&';
    }
    dataString += textarea.name + '=' + textarea.value;

    ajaxRequest.open('GET', 'email.php?' + dataString, false);
    ajaxRequest.send(null);

    var response = ajaxRequest.responseText;

    if (response === '') {
        wrapper.innerHTML = '';
        wrapper.innerHTML = '<h2>Comment received!</h2>';
    } else {
        wrapper.innerHTML = ‘’;
        wrapper.innerHTML =<p>Something went wrong!</p>;
    }
}

Way back in the beginning, we wrote:

1
var ajaxRequest = new XMLHttpRequest();

This is what we use to communicate with our PHP file. First we use the open method and send our dataString to email.php and then we send it. Next, we get the responseText and since we’re just sending a string, if the it’s successful, an empty string is returned. We can then check to see if that’s what was returned and if it was, tell our user that they were successful otherwise, we can tell them something went wrong. We used the GET method because when using Ajax, POST is only needed when you’re sending a larger chunk of info, we’re sending a pretty simple string, so we can just use GET.

Here’s a quick example of email.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

    if (isset($_GET['name'])) {
        $name = $_GET['name'];
    } else {
        $name = 'No name entered';
    }
    if (isset($_GET['email'])) {
        $email = $_GET['email'];
    } else {
        $email = 'No email entered';
    }
    if (isset($_GET['company'])) {
        $company = $_GET['company'];
    } else {
        $company = 'No company entered';
    }
    if (isset($_GET['comments'])) {
        $comments = $_GET['comments'];
    } else {
        $comments = 'No comments entered';
    }

    // email code here

?>

And that’s it. Less than 50 lines of JavaScript and I’m pretty sure you end up writing the same amount of code if you used jQuery along with still needing to load jQuery. I’m not saying one way is better than the other, writing Ajax with jQuery is easier, especially if you’re still new to it. But I like writing good old regular JS and this turned out to be a lot easier than I was expecting. And since IE7 doesn’t recognize querySelector, the form will just work like a regular HTML form and if most of your visitors are using modern browsers, it’s not really something you’ll have to worry about.

One Response to Client side form validation with JavaScript that even works in IE8

  1. sepiott says:

    I am pretty sure, that to prevent the event in IE8 you have to use the global event object:
    event.returnValue = false;

    Thanks for this great article, even though I don’t like it that you write your “Required” in the textareas 😉

    I always appreciate it, that you use vanilla js.

Leave a Reply

Your email address will not be published. Required fields are marked *