Programming Articles - JavaScript, XHTML, CSS, Java
Sunday, 31 January 2010
JavaScript Form Validation
Want to validate user input for an (X)HTML form without embedding a single line of JavaScript, without having to worry about violating semantics, and all the while providing a reactive, user friendly experience?
Introducing GValidator - a powerful, extensible yet easy to implement JavaScript library that provides constant feedback during form completion. To use the library all you need to do is include it.
Table of Contents
- Project goals
- Download
- Examples
- XHTML API
- Options
- Design
- JS API
- Extending with Plugins
- I8N
- Extending with OOP
- Browser support
The Aim
The aim of GValidator is to provide the following:
- A user-friendly experience for our visitors
- Semantically clean code
- Standards compliant code
- Cross browser compatibility
- Reusable JavaScript code
- Code flexibility and extensibility
The Code
GValidator now has a Google Code project. To get the latest version, post bugs, comment on or just look about visit: http://code.google.com/p/gvalidator
- Download the GValidator library, along with examples and CSS
Actually, for basic forms no extra coding is needed other than to include the JavaScript file and to add appropriate class names to your form fields. Here is an example form:
<form action="/action/" method="post" class="gform" >
<input type="text" name="firstname" class="firstname required" />
<input type="text" name="lastname" class="lastname required" id="lastname"/>
<input type="text" name="subject" class="text required" id="subject" />
<input type="text" name="captcha" class="captcha required" id="captcha" />
<input type="text" name="phone" class="phone required" id="phone"/>
<input id="submit" type="submit"/>
</form>
There are a few things to notice here;
- The form is given a class attribute of "gform". This is what activates the automatic form validator
- The fields for validation are given various class names depending on how we wish to validate them. i.e. class="name", class="phone", class="text" etc.
- To make a field required, simply add the class 'required'. You can still use the library on non-required fields, as it will cleanse them and validate if not correctly completed.
- There is no embedded JavaScript functions or invalid semantic markup here. Just clean, straightforward XHTML
The Example
There are 4 examples, ranging from simple to advanced implementation:
- See the basic example of GValidator - no javascript coding required
- Plugin - extends GValidator with a validation function type for an IP 4 address
- Internationalization - translates GValidator into German using a translation file so that your forms will have internationalized client side validation.
- Customization - tailors the default behaviour of GValidator on a global and a per-form basis, using only basic javascript
Field Types (default XHTML API)
The following are the field types and corresponding class names that are included in the default implementation. They should cover most cases. If you require more than this or customisation, then you can extend the functionality as discussed below.
| Form element | Description | Class name |
| text | Generic text input. Allows any characters except the following - ().;<> and is not mandatory | text |
| text | Name field | name |
| text | Phone number field. Allows between 8 - 12 digits only. | phone |
| text | Email field | email |
| text | Captcha field | captcha |
| text | Re-Captcha field | recaptcha |
| select | Generic combo box. Requires the user to select an option with a non-empty value | select |
| radio group | Generic radio group. Requires that the user selects at least one of the options | radio |
| check box | Generic checkbox group. Requires that the user selects at least one of the options | checkbox |
| password | Password field. Requires a password of at least 8 characters, and containing one or more of a digit, lowercase and uppercase characters. | password |
| password | Password confirmation field. Verifies that the confirmed password is the same as 'password'. | confirmpassword |
GValidator Options
GValidator has the following options, passed in to a variable with name ONEGEEK.forms.GValidator.options.
This variable is a literal object, containing key/value pairs.
| Parameter | Accepted Values | Description |
| reqShow | [Boolean] | Automatically add the required char to labels? (Defaults to true) |
| reqChar | [String] | Character used to indicate a required field (Defaults to '*') |
| reqPlacement | ['after', 'before'] | Position of required character. Can be 'before' or 'after' (Defaults to 'after') |
| autoFocus | [true,false] | Automatically focus the first form element on page load (Defaults to true) |
| supressAlert | [Boolean] | Suppresses the javascript alert on an invalid form submission. |
| highlightFields | [Boolean, String] | If not false, Will apply a class name of 'highlight' or the value of String to any invalid field on form submission attempt. |
| Element level messaging display options | ||
| eMsgFormat | ['open','compact'] | How to display messages next to the field. |
| 'open' refers to always showing the message (Default) | ||
| 'compact' only shows if the user performs an event on the field's icon. | ||
| eMsgEventOn | [String (DOM Event)] | Only used if eMsgFormat'compact'. Event used to trigger message display toggle (Defaults to 'click') |
| eMsgEventOff | [null, 'click', 'mouseout' ...] | Only used if eMsgFormat'compact'. Event used to trigger message hide toggle. (Defaults to 'click') |
| Cannot be the same as 'eMsgEventOff' (they would cancel each other out) | ||
| Form level messaging display options | ||
| fMsgFormat | [null, String, Function] | How to display errors at the form level. |
| null displays an alert to the user indicating there are errors to be corrected. See fMsg to override default message. (Default) | ||
| String Pass in an id reference to a container div to place the errors in as a <ul"gvErrorsList"> | ||
| Function To do something custom on form submission error, pass in a function that accepts 1 parameter containing all of the error fields (ONEGEEK.forms.AbstractFormField[]) | ||
| fMsg | [String] | A string alert to display on error. (Defaults to "Please correct the highlighted errors!") |
| Image parameters for 'compact' messages | ||
| icons: { | [Object] | |
| ok | [String] | Path to the ONEGEEK.forms.FIELD_STATUS_OK state icon |
| info | [String] | Path to the ONEGEEK.forms.FIELD_STATUS_INFO state icon |
| error | [String] | Path to the ONEGEEK.forms.FIELD_STATUS_ERROR state icon |
| } | ||
GValidator Library Design
The library was designed with simplicity and extensibility in mind. The basic idea was to create an abstract class hierarchy that could be quickly and easily extended to change the validation function for a new field type. This hierarchy exists in three tiers allowing for the following object types:
- One third (top) level AbstractFormField class, which provides the skeleton that all AbstractFormField subclasses inherit from
- A finite number of second level AbstractFormElements which provide the basic implementations for the different form elements (i.e. <input>, <select> etc.)
- An infinite number of first level ConcreteFormElement objects which provide the concrete validation implementations (i.e. validate a phone number field)
By implementing the library in this way, we allow for simple extensibility by implementing subclasses at the lowest level.
JavaScript API
Read the JavaScript API or download it from Google Code.
Class Hierarchy

Extending GValidator
Creating new validation types for GValidator is easy, they are added in the form of plug-ins. All you need to do is add object keys to the ONEGEEK.forms.GValidator.plugins object with the class name of the validator you wish to add.
Customisation example
Let's say we'd like to create a new validator for an IP 4 Address type on a text field, using the class name 'ip4address'.
The validation function must:
- Validate the input of an IP 4 Address type i.e. 127.0.0.1
- Remove non-allowed characters from the field before validation
- Have custom messages for each state of the field
- Additionally, the validator must highlight the field on error and clear the highlight on success
Step 1: Create the plugins object and add your new type and extend a type
Place the following object in an external JavaScript file after gvalidator.js has been added to the page.
The new type will use the className 'ip4address' to activate the validator on the field.
ONEGEEK.forms.GValidator.plugins = {
ip4address: {
_extends: 'AbstractTextField',
...
};
Note that the _extends key is set to 'AbstractTextField' because we are validating a Text field. Other options are 'ComboBox', 'RadioButton' or 'Checkbox' at the second level (see above). Of course, you can extend existing elements such as 'NameField' if you wish.
Step 2: Override existing instance variables
Here we override the AbstractFormField messages and AbstractTextField regex and cleanRegex variables. These last variables are used to validate the data and clean out invalid characters respectively (Note: regex has been shortened for display).
ONEGEEK.forms.GValidator.plugins = {
ip4address: {
...
regex: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2
cleanRegex: /[^0-9\.]/g,
contextMsg: 'Please enter a valid IP 4 Address i.e. 127.0.0.1',
errorMsg: 'Please enter a valid IP 4 Address i.e. 127.0.0.1',
successMsg: 'Thanks',
...
}
};
Step 3: OPTIONAL Override validation and other functions
If you are content to keep the validation behaviour consistent with other text fields, then you can stop here - how easy was that?
If, however, you want to do some custom validation behaviour then we need to override the existing validate() function:
ONEGEEK.forms.GValidator.plugins = {
ip4address: {
...
validate: function() {
if(!this._validate()) {
this.highlight();
} else {
this.unHighlight();
}
},
highlight: function() {
this.field.style.background = 'rgb(200,0,0)';
},
unHighlight: function() {
this.field.style.background = 'rgb(255,255,255)';
}
}
};
Note that the validate function makes a call to _validate(). This is actually the parent (previously overridden) validate function. In fact, any attribute or function that you override will be preserved with a '_' prefix so that you can make reference to it if needed. This means, we can call the existing validation function that we like, and enhance it by highlighting the field. Also note that you can attach any function/attribute that you desire and they will be attached to the this of the new object type, effectively extending the class. Be careful not to clash with existing variables/functions unless you intend to (Check out the API or download it from Google Code if unsure)
Full customisation code
Here is the entire code listing for the customisation (regex has been shortened for display):
ONEGEEK.forms.GValidator.plugins = {
ip4address: {
_extends: 'AbstractTextField',
regex: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2
cleanRegex: /[^0-9\.]/g,
contextMsg: 'Please enter a valid IP 4 Address i.e. 127.0.0.1',
errorMsg: 'Please enter a valid IP 4 Address i.e. 127.0.0.1',
successMsg: 'Thanks',
validate: function() {
if(!this._validate()) {
this.highlight();
} else {
this.unHighlight();
}
},
highlight: function() {
this.field.style.background = 'rgb(200,0,0)';
},
unHighlight: function() {
this.field.style.background = 'rgb(255,255,255)';
}
}
};
Internationalisation
Internationalising client-side validation in GValidator is easy. It should work with any almost any language.
Note: GValidator does not change the labels on the form or any other content on the page other than content related to the validation of the form. It assumes that the page itself has already been translated and requires form validation specific to that language.
To specify a language translation for a form, simply do the following:- Apply the W3C attribute 'lang' to the <form> with the value of the language to translate into i.e. lang="DE" (see a list of valid values)
- Create a variable with the format ONEGEEK.forms.GValidator.translation.<LANG> i.e. ONEGEEK.forms.GValidator.translation.DE (Note that uppercase is important)
- In that Object, override messages/parameters for existing validator types using the className of the field you wish to override i.e. 'username'
- To set defaults across ALL validator types, use the special top-level key 'defaults'. These will only be used in the case that a translation is not available for a given class
I8N example
Create a form specifying the lang attribute:
<form lang="DE" ...>
Create an JS file containing a variable like the following:
ONEGEEK.forms.GValidator.translation.DE = {
defaults: {
successMsg: 'Danke',
contextMsg: 'Bitte füllen Sie',
errorMsg: 'Kaputt! Es wurde ein Fehler beim Überprüfen diesem Bereich',
emptyMessage: 'Pflichtfeld, füllen Sie bitte.',
},
firstname: {
contextMsg: 'Wir möchten Sie von Ihrem Namen zu nennen'
},
...
};
To set the form level error alert messag, override the 'fMsg' property in the options config (see Customisation abve) like the following:
ONEGEEK.forms.GValidator.options = {
fMsg: "Bitte korrigieren Sie die markierten Fehler!"
};
Extending GValidator (Advanced)
If you prefer to code in a more OOP (and I use that term very loosely) type approach, with the added benefit of code completion in some editors, this might be for you.
To create your own validation types, you need to do the following things:
- Create a class at the first level, overriding the AbstractFormElement of your choice. i.e. To create a UsernameFormField class you would subclass the AbstractTextField class
- Override any instance variables of ONEGEEK.forms.AbstractFormField if necessary (Read the JavaScript API or download it from Google Code)
- Override the validation function (and any other functions necessary) to do the custom form field validation
- Register the new class with FormFieldFactory
Customisation example
Lets say we would like to create a new field type username for validating usernames. The requirements are as follows:
- It must be between 8-10 alpha-numeric characters
- It must not already exist in the database
- It is a required field
Step 1: Subclass AbstractFormElement
Create a new class ONEGEEK.forms.GenericTextField and subclass ONEGEEK.forms.AbstractTextField.
ONEGEEK.forms.UsernameTextField = function(field) {
this.field = field;
...
}
ONEGEEK.forms.UsernameTextField.prototype = new ONEGEEK.forms.AbstractTextField();
Step 2: Override existing instance variables
In this case, we need to make the field required and we want to validate the field using a regular expression. We can override the instance variables in ONEGEEK.forms.AbstractTextField to achieve this. Override the following instance variables like so:
this.field = field; // This MUST alwys be here
this.regex = /^([a-zA-Z0-9-\'\s]{8,10})$/g
this.cleanRegex = /[^0-9a-zA-Z-\'\s]/g
this.errorMsg = 'Your username must be between 8 and 10 characters';
this.contextMsg = 'You will use this to login. It must be between 8 and 10 characters';
Step 3: Override the validation function
The validation function is where most of the action happens. This function is responsible for checking whether the data has been modified and is valid, and setting the appropriate state of the field (INFO, OK, ERROR). This is where your custom AJAX code would go.
Assuming that an AJAX function called checkUsername(name, field) exists, which takes a username and a ConcreteFormElement object, this is how you would implement the validation function:
this.validate = function() {
this.clean();
this.pattern = new RegExp(this.regex);
var validated = this.pattern.test(this.field.value);
if (validated) {
// Regex validated, now use AJAX to check if username exists
// On successfull AJAX validation set state to OK
// On failure of AJAX validation set state to ERROR
checkUsername(this.field.value, formField);
} else {
if (this.modified == false) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_ERROR);
}
}
return true;
}
Step 4: Register the class with FormFieldFactory
Your custom validation function wil never be used unless you register with FormFieldFactory and tell it which classes you want it to automatically handle. Let's say that you want to use the class "username" with this function as in the example form element below:
<input type="text" name="username" class="username"/>
To get your new function to handle this, you simply do the following:
formFieldFactory.registerFormField('username', 'UsernameTextField');
Now when you load the page your new function will handle the validation!
Full customisation code
Here is the entire code listing for the customisation:
ONEGEEK.forms.UsernameTextField = function(field) {
this.field = field;
this.regex = /^([a-zA-Z0-9-\'\s]{8,10})$/g
this.cleanRegex = /[^0-9a-zA-Z-\'\s]/g
this.errorMsg = 'Your username must be between 8 and 10 characters';
this.contextMsg = 'You will use this to login. It must be between 8 and 10 characters';
this.validate = function() {
this.clean();
this.pattern = new RegExp(this.regex);
var validated = this.pattern.test(this.field.value);
if (validated) {
// Regex validated, but use AJAX to check if username exists
// On successfull AJAX validation set state to OK
// On failure of AJAX validation set state to ERROR
checkUsername(this.field.value, this);
} else {
if (this.modified == false) {
this.setState(ONEGEEK.forms.FIELD_STATUS_INFO);
} else {
this.setState(ONEGEEK.forms.FIELD_STATUS_ERROR);
}
}
return true;
}
}
// Subclass Abstract FormField class
ONEGEEK.forms.UsernameTextField.prototype = new ONEGEEK.forms.AbstractTextField();
// Register the field types with FormFieldFactory
formFieldFactory.registerFormField('username', 'UsernameTextField');
GValidator Browser Support
The library has been tested successfully on the following browsers on Windows:
- Internet Explorer 6.0
- Internet Explorer 7.0
- Internet Explorer 8.0
- Mozilla Firefox 1.0.6
- Mozilla Firefox 2.0.0.7
- Mozilla Firefox 3.0
- Mozilla Firefox 3.5
- Safari 3 Beta
- Opera 9.25
- Netscape Navigator 8.0
- Netscape Navigator 9.0.0.1
- Google Chrome
and the following browsers on Linux:
- Mozilla Firefox 2+
- Opera 9.62
- Epiphany 2.26
| < Prev | Next > |
|---|


