Tutorial 11 - Form Validation

Tutorial 10 - Menuing Systems - Tutorial 12 - Smart Forms

Validation routines test for required strings whether a specific value, a range of accepted values or a pattern of an accepted format. Validation is required in forms, whether fill-in or smart forms and also in routines that manipulate data. Testing for valid numerics and whether the numeric is in a required range is also a part of data validation.

The best method of form validation is to choose form controls that restrict value selection to known pretested quantities. Examples of these controls are radio buttons, check boxes and select lists. However there are times when they are not always appropriate. In these cases you can let the user complete the form and then validate it or validate on each individual entry.

Common Validations Needed

There are many types of common validations that you should be ready to do on a form. These checks include:

  • guaranteeing a minimum length (eg. password of 5 or more characters)
  • making sure an entry matches a specific word
  • making sure two entries agree (eg. double entry of password)
  • validating a number format or range
  • checking the format for a pattern (eg. is this like a mail address)
  • checking two or more fields for consistent results such as married:no and name of spouse field filled in.

However do not make any false assumptions in what the entry will be. Assuming that age:12 children:3 is in error may require checking the state address ;-] ;-] Common mistakes seen on some entry forms are:

  • Assuming a specific format for telephone numbers. Some numbers require an area code. And some international numbers are NOT 3x3x4 digits long. And of course letters are still valid!
  • Not all addresses are ZIP codes! In fact only one country uses them. There is a large variation in postal codes.
  • Dates have many variations depending on locale. Separate entry boxes for each component (year/month/day) is a safer method of entry.

Validating Before Form Submission

The onSubmit event can be used to call a function to check all fields that require validation before sending a form. The values to be checked (or perhaps the entire form) are passed as parameters. The validation function must return a true if ready to submit or a false if not ready. It also makes sense to use dialog boxes to indicate the nature of the error. An example of a simple call to a validating function is:

<form id="SurveyForm" action="http://www.flintstone.ca/survey/"
      method="post" onSubmit="return validate(fld1,fld2);"></form>

An alternative method uses a simple button with an onclick event. Either the submit action is suppressed by placing onSubmit="return false;" in the form element or removing the form element altogether!

<form id="foo" action="?" method="post" onSubmit="return false;">
. . .
<input value="Check Form!" onclick="validate(fld1,fld2);" />
</form>

Validating On A By Entry Basis

Many forms are best validated on a by entry basis. A function to validate the contents of an entry box can be called by the onBlur event. onBlur occurs whenever an element such as an entrybox loses focus. That means the entry is checked when you click on a new entry field or another spot in your window or use the tab key to move off the entry.
NOTE: Read my Bugs Tutorial to see how some browsers can create endless loops when blur and focus events are encountered. Another event that can be used is onChange which only does the validation when you move off the entry box and that entry has changed. The next example brings up an alert dialog if the correct word is not entered.

Input the word STOP in the following entry box:
Then click somewhere outside of the box to test!  

<form id="pass" action="" method="post" onSubmit="return false;">
<p>Input the word STOP in the following entry box:<br>
Then click somewhere outside of the box to test!  
<input id="i1" type="text" value="" onclick="return false;"
       onBlur="isit('i1','STOP'); return true;"></p></form>

And here is the JavaScript checking routine. Note that the validation is case sensitive. The onSubmit event in the form element is used to suppress the return key and the onclick event suppresses other key clicks.

function isit(id,expectedval) {
   inputval=document.getElementById(id);
   if (inputval!=expectedval) {
      alert('You must enter the word '+ expectedval);
      } else {alert('ok')}
   }

Validating On A Keystroke Basis

Sometimes you may want to restrict invalid characters from being entered into a control or do some form of on-the-fly reformatting. This requires catching individual keystrokes with the onKeyPress event. An example of this is:

document.onkeydown=keyHit; // register key pressed event
upArrow=38; dnArrow=40;  // names for important keys
function keyHit(evt) {
	thiskey=window.event.keyCode;
	if (thiskey==upArrow) {alterSelection(-1)}
	if (thiskey==dnArrow) {alterSelection(+1)}
	}

Notice that instead of using an element attribute, the event is registered in JavaScript. The evt object can be tested if you need to restrict keystrokes to specific zones or elements. You can use an alert(thiskey) method to show the specific keyCode. It helps to make a name synonym for any keyCode that is being used such as pound or percent.

Brute Force Validation

Brute force evaluation is programming that takes the simplest approach or uses very crude assumptions. It is easy to get the code in place and most often does the job. Stepwise refinement can then be applied. But the resulting code is not elegant and often quirky. As an example suppose that a field is intended to hold a person's surname and is a mandatory field. The first approach is to check for an empty string. That is a start but surely a person's last name is at least 2 characters long. And only a few punctuation symbols (such as hyphen and apostrophe) are allowed and no digits please!

There are several String object functions and properties that can make your brute force checks easy! You may want to refer to Appendices - Objects for the complete list.

  • entry=entry.toUpperCase() will change any lowercase characters to uppercase. This way you do not have to check for each of ANN, ann, Ann, etc.
  • x=entry.length; will return the length of the string entry.
  • x=entry.indexOf(char) will return the first position of char within the string entry. Returns 0 if not found!
  • x=entry.lastIndexOf(char) will return the last position of char within the string entry. Returns 0 if not found!
  • x=entry.indexOf(char,start) will return the first position of char within the string entry starting at position start. Returns 0 if not found!
  • x=entry.charAt(p) will return the character at the specific position p. Combined with a loop such as for (p=1;p<entry.length;p++) {BLOCK} which scans the entire string, you can watch for problem characters.
  • x=parseInt(entry) will return an INTEGER number from the string. BEWARE: truncation can occur!
  • x=parseFloat(entry) will return an DECIMAL number from the string. BEWARE: truncation can occur!

Validation with regular expressions is more elegant and much easier than the brute force technique, once you master the syntax. If your scripts rely heavily on input validation, it is well worth the effort to learn how to use them.

E-mail Address Validation

A good example of brute force validation is checking an e-mail address. The first version would check for the @ symbol. Refinements would check for at least one dot after the @ and characters before, between, and after the symbols. Further refinement would find the last dot and make sure that there is at least two alphabetic characters after it. Very thorough validation would check any two character final character combination (Top Level Domain or TLD) against a list of valid ISO country TLD's. Also one should scan for illegal punctuation never found in e-mail addresses.

An example of a brute force email entry field test routine (some but not all of the possible checks!) can be found here. You can use it as a good start for your own validation routine.

Validation with regular expressions is much easier. If your scripts rely heavily on input validation, it is well worth the effort to learn regular expression syntax.

Postal Code Validation

Another example of brute force validation is checking postal codes. As each country has their own format, you should use the country address value to select the required validator function.

As an example of how a postal code validator function is constructed, first review Canada's Postal Code rules:

  1. Postal code must be exactly six characters.
  2. Letters and numbers alternate.
  3. Certain letters never occur (I AND O).
  4. The first character is even more restricted as it designates region. Regions are (from east to west, then north): A,B,C,E,G,H,J,K,L,M,N,P,R,S,T,V,X,Y
function isPostCode(entry){ // CANADIAN CODES ONLY
strlen=entry.length; if (strlen!=6) {return false}
entry=entry.toUpperCase();    // in case of lowercase characters
// Check for legal characters in string - note index starts at zero
if ('ABCEGHJKLMNPRSTVXY'.indexOf(entry.charAt(0))<0) {return false}
if ('0123456789'.indexOf(entry.charAt(1))<0) {return false}
if ('ABCDEFGHJKLMNPQRSTUVWXYZ'.indexOf(entry.charAt(2))<0) {return false}
if ('0123456789'.indexOf(entry.charAt(3))<0) {return false}
if ('ABCDEFGHJKLMNPQRSTUVWXYZ'.indexOf(entry.charAt(4))<0) {return false}
if ('0123456789'.indexOf(entry.charAt(5))<0) {return false}
return true; }
Postal Code String Test

Once again validation with regular expressions is much easier, once you master the syntax. If your scripts rely heavily on input validation, it is well worth the effort.

Password Controlled Pages

One common validation is requiring a password to enter a page. Use of a password control box on the form and its value within the JavaScript function are all that is required. The html fragment is:

<fieldset><legend>Test Form</legend>
<label for="pw">Password:</label>
<input id="pw" type="password">
<input id="act" type="button" value="View Utilities" onClick="doPw('pw');">
</fieldset>

And here is the JavaScript function. Note that to be of any value both the comparison value and the referenced page must be encrypted. FlashPeak offers CryptHTML for encoding html and javascript documents. Another more expensive solution is invisitec.com.

function doPw(objectId) {
entry=document.getElementById(objectId).value;
if (entry=="test") {
   top.location.href="http://home.cogeco.ca/~ve3ll/utility.htm";
   } else {
   alert("Sorry - You must sign agreement to access utilities");
   }
}