COM271, Week 8
JavaScript Form Validation
Syllabus | Table of Pages | Assignments | References and Useful Links
There are many online models to help you with programming javascript forms. When you are beginning, it is difficult to know what to do first, even with a pile of scripts at your fingertips. In what follows, I suggest steps to take to develop a validation script. I divide the task into a preliminary step, then two variations as models for you to consider. By going through these carefully, you can gain a better understanding of validation methods; in some cases (very simple forms), the simpler method might be preferred because it is simple and easier to program.
Preliminary Step
Start with completing your html form. Make certain that you provide an id attribute (e.g., id="firstname") for every element that you are going to validate. Typical validations include checking to see whether an input box has any content, whether letters or numbers were entered, or whether an input matches a pattern (e.g., social security numbers with xxx-xx-xxxx numerical patterns).
Within the form, you must include an event handler that calls your javascript validation function. Two ways to do this are:
- <form onsubmit='return validate_form()' .... > (i.e., within the form element)
- Note that with this option, you must have a submit button (i.e., of type = submit):
<input type="submit" value="Submit" >
- Note that with this option, you must have a submit button (i.e., of type = submit):
- <input type= 'button' onclick="validate_form()" value="Submit" ..... > (i.e., within a button used to submit the form)
Here is a simple form, using the first option. I've included two input fields for a typical first and last name; I've decided that each field is required, so I am going to check each one. That is, I'm going to check to see whether the first name field has any content at all, and I'll check the last name field by seeing whether it contains letters. Okay, checking for letters would accomplish the same goal, checking to see whether there is content, as the first approach, but sometimes you will accept anything and sometimes you want words. The forms below are live, so you can follow along if you are on-line:
Before I attempt to make my validator do anything, I take the preliminary step of checking my form's event handler (will it respond when I click the button) and its connection to the script. Here, the javascript validator has a single response, to call an alert box with a simple message. If clicking on the submit button displays an alert box with my message, I'm ready to get started. Here's all of the code:
Script
<script type="text/javascript" >
function validate_1()
{
alert('Testing: Button works and script is called...');
return true;
}
Form
<form onsubmit="return validate_1()" action="#form1"><fieldset>
<legend>
Enter Name:</legend>
<table id="form1"width="200px">
<tr><td>First</td><td>Last</td></tr>
<tr><td><input type="text" size="20" id="firstname" /></td>
<td><input type="text" size="20" id="lastname" /></td></tr></table>
</fieldset>
<input type="submit" value="Validate Form (Preliminary)" />
</form>
(You may have noticed that I set the action attribute in the form,
<form onsubmit="return validate_1()" action="#form1">;
I have embedded a named anchor on the page, just above the form,
<a name="form1" id="form1"></a>.
When the form is ready to submit, it calls the current page and looks for the within-page named anchor, loading the page just above the form. I use that in the forms below to prevent the annoyance of having to scroll down to find the form whenever the submit is successful.)
A "Good" Validator: One Alert Box listing all errors at once.
In this model, the form is evaluated, one element at a time. We could easily make each error produce an alert box, one error at a time, but the user experience would be torturous. Instead, we'll go through the same evaluations, but we will create a string that lists all of the errors, and only produce a single alert box that lists all of the errors at one time. The form looks the same:
The form is the same, except that the event handler calls a different function, validate_2()
<form onsubmit="return validate_2( )" action="#good">
Also, because I have already used the unique identifiers fname and lname in the previous form on this page, I had to use new identifiers fname3 and lname3 in this form. I have also had to modify the functions.
Here are the scripts:
var strErrorMsg;
function validate_2()
{
strErrorMsg="";
notEmpty_2(document.getElementById('fname3'), 'Enter your first name.' );
isAlphabet_2(document.getElementById('lname3'), 'Enter your last name.');
if(strErrorMsg=='')
{
alert('Form is ready for submission.');
return true;
}
alert('Errors encountered:\n'+strErrorMsg);
return false;
}
function notEmpty_2(elem,helperMsg)
{
if(elem.value == "")strErrorMsg=strErrorMsg+helperMsg+"\n";
}
function isAlphabet_2(elem, helperMsg)
{
var alphaExp = /^[a-zA-Z]+$/;
if(!(elem.value.match(alphaExp))) strErrorMsg=strErrorMsg+helperMsg+"\n";
}
How does the "good" form validator work?
At the top of the script, before and outside of any functions, I create a variable called strErrorMsg. The prefix str is deliberate, helping me to remember that this variable contains a string. The variable is declared outside of all functions, giving it a global scope: this means that I can use that variable inside of all functions (i.e., it is visible everywhere to any function on the page). This also means that I don't have to pass it into a function or return its value.
Inside the function validate_2(), I assign a blank string to strErrorMsg. I then simply call the functions to check for errors. I use two functions, notEmpty_2() and isAlphabet_2(). I pass a connection to each form element using getElementById() and an error message. If I encounter an error, I merely append a new piece of string (i.e., the error message that I just passed) to strErrorMsg.
strErrorMsg=strErrorMsg+helperMsg+"\n";
I am using the string concatenation operator (you thought it was a plus sign, didn't you?) to join the new string to the old one (which started as an empty string). I also concatenate an '\n' escaped character which adds a line break.
If there are any errors, the original blank string will be replaced by one or more lines specifying errors. After I have called all the functions, I check to see whether strErrorMsg is still blank
if(strErrorMsg=='')
and if it is, there weren't any errors: the validate_2() function returns a true to the onsubmit event handler, and the form can be submitted (here, it will then call the current page and within-page anchor named "form2," which I explained above). If there is an error, the string will be shown in an alert box and submission stopped.
Play with the form online and study the code carefully. Make sure you understand and can explain how it is working.
In programming this version, add each new function call one at a time, testing the form and any new functions as you go. Don't try to program big chunks (more than 1-2 lines at a time) without checking everything.
Best Model: Messages on page, listing all errors at once.
The "good" model is nice because there is only one alert box and it lists all of the errors. Still, we can do better.
In this model, we want to list error messages again, but this time we will write them onto the html page itself. We will also alter the form appearance through CSS to provide clear indications of which form elements (input boxes) have errors.
Once again, here is our form. I have altered the onsubmit to now call function validate_4(), and I have provided new identies to make the first and last name input boxes unique. But the form still looks the same. I have also included a new div, containing an identified paragraph (now containing a non-blank space), which I have displayed with a dotted border so that you can see where I have set aside space. In this space, I intend to display error messages. This is the div and its paragraph:
<div id="errors"> </div>
The div is styled to show the light dotted line and any type appearing in it will be red.
Here are the new scripts:
var strErrorMsg;
function validate_4()
{
strErrorMsg="";
var parerr = document.getElementById('errors');
notEmpty_4(document.getElementById('fname4'), 'Enter your first name.' );
isAlphabet_4(document.getElementById('lname4'), 'Enter your last name.');
if(strErrorMsg=="") {
parerr.innerHTML='<p>Form is validated and ready for submission.<p>';
return true;
}
else
{
parerr.innerHTML='<h4>Errors—please correct and resubmit:</h4>'+strErrorMsg;
return false;
}
}
function notEmpty_4(elem,helperMsg)
{
elem.style.backgroundColor="#ffffff";
if(elem.value == "")
{
strErrorMsg=strErrorMsg+'<p>'+helperMsg+'</p>';
elem.style.backgroundColor="#f99";
}
}
function isAlphabet_4(elem, helperMsg)
{
var alphaExp = /^[a-zA-Z]+$/;
elem.style.backgroundColor="#ffffff";
if(!(elem.value.match(alphaExp)))
{
strErrorMsg=strErrorMsg+'<p>'+helperMsg+"</p>";
elem.style.backgroundColor="#f99";
}
}
How does the "best" form validator work?
Once again, the form's event handler calls function validate_4(), which begins by setting the (global) error message string, strErrorMsg, to a blank string.
In addition, a variable is created to hold a connection to the div set aside for errors,
var parerr = document.getElementById('errors');
Validate_4() then works its way through the form, as before, calling error functions and passing element connections and error messages.
Within each function, when an error is encountered, the error message is added to the error string. This time, however, the individual error messages are enclosed in html tags
strErrorMsg=strErrorMsg+'<p>'+helperMsg+'</p>';
Also, when an error is encountered, the element's style method is used to assign a new value to the background color. Note the javascript equivalent to the CSS background-color is backgroundColor
elem.style.backgroundColor="#f99";
(At the beginning of each error check function, we have set the background color back to white (#fff) in case it had been altered by a previous error.: elem.style.backgroundColor="#ffffff";)
Again, when all of the error check functions have been called, the error message string is evaluated to see whether it is still an empty string.
- If so, a message is sent attached to the div for errors
parerr.innerHTML='<p>Form is validated and ready for submission.</p>';
Note the use of the innerHTML method to change the contents of this div to the html containing the error messages. Yes, even the content of a page is accessible (and changeable) to a javascript coder: Javascript rules!!! - If not (i.e., an error has been found), the error string is sent to the div instead
parerr.innerHTML='<h4>Errors—please correct and resubmit:</h4>'+strErrorMsg;
Once again, play with the form online and study the code carefully. Make sure you understand and can explain how it is working.