Introduction
Server side validation is the only way to reliably validate forms. Using client-side JavaScript exclusively should be avoided for the following reasons:
- A device may not have JavaScript available
- A user might have turned JavaScript off
- An administrator might have disabled JavaScript on a network
As well as making sure that all your forms are validated on the server, you can use JavaScript to validate forms as well. Validating a form twice is not a waste of time
as we can use JavaScript to unobtrusively enhance the usability of the form. The unobtrusive JavaScript will stop the form submission if JavaScript is available
and speed up the form submission process. As JavaScript is client side, users won't have to wait for the page to reload if errors have been made submitting
the form (this is particularly useful to users with slow connections).
So you can see what we're aiming to do, check out this fully functioning
example.
Resources for this tutorial
Download the sample before beginning this tutorial.
Start by opening the file validate-forms-with-javascript.htm. This is a sample section of the form we're going to make more usable and attractive using JavaScript:
Getting started
The form we're going to validate contains just two required fields:
- E-mail
- How useful did you find this article?
Both of these fields are required for the form to be submitted. The HTML to create this form is as follows:
<html>
<head>
<title>Webcredible - JavaScript tutorial - form validation</title>
<style type="text/css">@import "css.css";</style>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<form action="#">
<ul>
<li><label for="email">E-mail <img src="req.gif" alt="Required" /></label>
<input class="reqemail" id="email" value="" /></li>
<li><label for="question">How useful did you find
this article? <img src="req.gif" alt="Required" /></label>
<input class="reqquestion" id="question" value="" /></li>
</ul>
<input type="submit" value="Submit form" />
</form>
</body>
</html>
The fields are labeled as being required by inserting an image within the <label>
tag with alt="required"
.
onsubmit for testing
Initially, we'll also insert an onsubmit
with a call to our form validation script. This will help us test the page as the JavaScript develops.
It'll be removed at the end of this article and a function call will be assigned to the form itself with JavaScript.
We'll insert the HTML extra code as follows:
<form onSubmit="validateForms()" action="#">
The JavaScript
We'll create a JavaScript file and call it js.js. The function we've called on the onsubmit
command is called validateForms()
,
so we start by creating that empty function at the start of the js.js file:
function validateForms()
{
}
The validateForms()
function is the root function that will be used to control how the form is validated. The validation script will then be applied
to all forms. Let's start by getting an HTML object collection of any form
on the HTML page:
function validateForms()
{
if (!document.getElementsByTagName) return false;
elementsForms = document.getElementsByTagName("form");
}
Looping
The next step in the validation process is to loop through the forms and validate them. All forms will be handled in the same way. We'll do this using a for
loop
to loop through the HTML object collection, with each form being passed to a new function called validateForm()
:
function validateForms()
{
if (!document.getElementsByTagName) return false;
elementsForms = document.getElementsByTagName("form");
for (var intCounter = 0; intCounter < elementsForms.length; intCounter++)
{
validateForm(elementsForms[intCounter])
}
}
function validateForm(currentForm)
{
}
Task order
At this point, it's probably useful to stop and think about how we might implement the JavaScript validation. If we return
to the form HTML, you will, of course, have noticed that we've applied a class to each of the required <input>
s:
<li><label for="email">E-mail <img src="http://www.codeproject.com/i/req.gif" alt="Required" />
</label><input class="reqemail" id="email" value="" /></li>
The e-mail <input>
has the class="reqemail"
assigned to it and the question <input>
has class="reqquestion"
.
These will be used to identify the <input>
s to the JavaScript as requiring validation and defining what type of validation they require.
We can now use getElementsByTagName
to access the class definitions on each of the input
s. When we used the getElementsByTagName
at the start of the article to create a collection of forms, we used the entire document as its parent.
elementsForms = document.getElementsByTagName("form");
We can also get all <input>
s contained by the form that we've passed to the validateForm(currentForm)
function:
function validateForm(currentForm)
{
var blnvalidate = true; var elementsInputs;
elementsInputs = currentForm.getElementsByTagName("input");
}
The next step is to loop through the <input>
s as we did at the start of the article with the forms:
function validateForm(currentForm)
{
var blnvalidate = true; var elementsInputs;
elementsInputs = currentForm.getElementsByTagName("input");
for (var intCounter = 0; intCounter < elementsInputs.length; intCounter++) { }
}
The final step in this function is to write an if
statement that recognises a required class name and validates that <input>
field:
if (elementsInputs[intCounter].className == "reqemail")
{
if (validateEmail(elementsInputs, intCounter))
{ alert('Please insert a valid email'); }
}
The completed function should look like this:
function validateForm(currentForm)
{
var blnvalidate = true; var elementsInputs;
elementsInputs = currentForm.getElementsByTagName("input");
for (var intCounter = 0; intCounter < elementsInputs.length; intCounter++)
{
if (elementsInputs[intCounter].className == "reqquestion")
{
if (validateText(elementsInputs, intCounter))
{
blnvalidate = true;
alert('You have not let us know what you think of the article');
}
}
else if (elementsInputs[intCounter].className == "reqemail")
{
if (validateEmail(elementsInputs, intCounter))
{
blnvalidate = true; alert('Please insert a valid email');
}
}
}
return blnvalidate;
}
With the function complete, we've now identified all <input>
fields that have a required class. All other <input>
s will be ignored
by the script. The email and question items must now be validated.
Validation
To validate the email, we'll create a simple function using a Regular Expression to check if the e-mail is valid. This is called when class="reqemail"
is found by the validation function:
function validateEmail(elementsInputs, intCounter)
{
var emailFilter=/^.+@.+\..{2,3}$/;
if (!emailFilter.test(elementsInputs[intCounter].value)) { return true; }
}
validateEmail(elementsInputs, intCounter)
will return true
if the e-mail address isn't valid. In the above example, this triggers an alert
in the validateForm(currentForm)
function. We'll check to see if the 'How useful did you find this article?' <input>
has any text entered:
function validateText(elementsInputs, intCounter)
{
if (elementsInputs[intCounter].value == "") { return true; }
}
Separating HTML, JavaScript, and CSS
The final task is to remove all JavaScript from the HTML page. The onsubmit
function we applied
to the <form>
at the start of the article can now be removed and we can apply the function call validateForms()
to all forms.
The opening <form>
tag should now read as follows:
<form action="#">
We should now apply the form onsubmit
function call to all form tags within the .js file.
function validateForms()
{
elementsForms = document.getElementsByTagName("form");
for (var intCounter = 0; intCounter < elementsForms.length; intCounter++)
{ elementsForms[intCounter].onsubmit = function () { return validation(this); } }
}
Finally, we register the event using the following script at the bottom of the js file (for more information about registering events,
see Simon Willison's Weblog):
function addLoadEvent(func)
{
var oldonload = window.onload;
if (typeof window.onload != 'function') { window.onload = func; }
else { window.onload = function() { oldonload(); func(); } }
}
addLoadEvent(validateForms);
If JavaScript is enabled, then the function call is applied to all form
s and any input
with reqEmail
and reqQuestion
will be validated automatically.
In conclusion
This solution demonstrates key advantages in using JavaScript to progressively enhance a form:
- The form is only validated by JavaScript if JavaScript is enabled.
- There is no JavaScript contained within the HTML, potentially separating web design from web development.
- Any errors, future enhancements can easily be made to a single file, significantly cutting down on development time.
Check out this fully functioning example.