Recently I put together a reusable Ajax form validation component that I’d like to share. It is a JavaScript object that collects the values of all of the elements in a form, sends it for processing to the server, and displays any errors. If there are no errors it submits the form. There are several benefits to this approach

  • Allows you to perform complex validation, such as verifying the uniqueness of a username, or checking something in the database…all without reloading the page
  • Allows you to use the same validation routine for both client-side validation and server-side validation
  • Reduces the amount of client-side code needed for validation

The JavaScript used in my example requires the Prototype library. My example uses PHP to perform the validation – more specifically, I’ve used several components of the Zend Framework (PHP5 only). The example uses:

  • Zend_Controller_* classes including the new RewriteRouter to handle the routing within the application
  • Zend_View to handle the output
  • Zend_View_Helper_* classes to build form elements
  • Zend_Config to read in configuration options
  • Zend_Filter to perform several field validations
  • Zend_Json to serialize PHP variables/objects to JSON objects

Did I need all of this stuff on the server-side to put together a simple form validation example? Heck no, but when I’m experimenting with new stuff I like to use a lot of new components so I can learn more about them and be prepared for when I actually do need to use all of this fire power. I’ve been following the Zend Framework carefully, so I wanted to use some of the stuff I hadn’t used yet – particularly the controller architecture.

The HTML and JavaScript

Ok, back to how this JavaScript is used. It’s actually really quite simple. First, you need to include the JavaScript files for both Prototype and AjaxFormValidator in the head of your HTML document:

1
2
<script src="/ajaxValidate/static/js/prototype.js"></script>
<script src="/ajaxValidate/static/js/ajaxFormValidate.js"></script>

Next, you add an ‘onSubmit’ handler to the form you’d like to validate – in this case, mine looks like this:

1
<form action="/ajaxValidate/index/success" method="POST" onSubmit="return submitForm(this);">

The form action is set to the page I’d like the script to go to if the validation is successful. The onSubmit calls a custom function that we still need to define. It passes ‘this’ as an argument – the ‘this’ refers to the form element itself.

Now we define the submitForm() function that the onSubmit of the form will call – it looks like the following:

1
2
3
4
5
6
function submitForm(form) {
	validator = new AjaxFormValidator(form,"/ajaxValidate/index/validate");
	validator.errorDisplay = 'inline';
	validator.inlineElem = 'errorDiv';
	return validator.validate();
}

This function first creates a new AjaxFormValidator object, passing it the form element (or the form id) and the url the validation request should be sent to. The next two lines setup the type of error display that should happen. The following error display types are supported:

  • alert: The default option. Displays all errors in a JavaScript alert box.
  • inline: Displays errors within an element that is defined on the page. You need to set the element name with validator.inlineElem. In this example, errors will be shown in a div with id=”errorDiv”.
  • none: errors won’t be shown to the user. The will be available as an array of errors in the errors property of the validator (i.e. validator.errors). If there are no errors the property will be set to false. Once you have the errors you can perform more advanced error handling/display to the user.

Lastly, validator.validate() will send the values in the form, in an HTTP POST, to the validation url you’ve provided (/ajaxValidate/index/validate in this case). If there are no errors the form will be submitted, if there are errors the will be shown (or not shown if you’ve chosen ‘none’ as the errorDisplay).

The PHP

Once the request is sent it will eventually arrive at the server for processing – in this case, through the magic of routing, it is going to end up in my IndexController in the validateAction method. This function is shown below:

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
public function validateAction() {
	$errors = $this->getErrors($_POST);
	if(count($errors) == 0) $errors = false;
	echo Zend_Json::encode($errors);
}
</php>
This function calls another method within the IndexController class called getErrors, passing in the entire array of POST arguments (values in the form).  It receives back an array full of error strings.  If there are no errors, it changes the value of the $error variable to false.  Lastly, it uses Zend_Json to convert the PHP array/Boolean into the equivalent JavaScript array/Boolean.  This string is printed and sent back to the client.
 
The getErrors function itself is very straightforward - it just does a couple validations and returns back an array of the errors.
<pre lang="php" line="1">
protected function getErrors($values) {
	$errors = array();
	if(!Zend_Filter::isRegex($values['fname'],'/^[a-z]+[a-z 0-9-_]*$/i')) {
		$errors[] = 'First Name is required and may only contain letters, numbers, and spaces';
	}
	if(!Zend_Filter::isRegex($values['lname'],'/^[a-z]+[a-z 0-9-_]*$/i')) {
		$errors[] = 'Last Name is required and may only contain letters, numbers, and spaces';
	}
	if(!Zend_Filter::isRegex($values['email'],'/^[_a-zA-Z-]+[._a-zA-Z0-9-]+@[a-zA-Z0-9-]+\.[.a-zA-Z0-9]+$/')) {
		$errors[] = 'Email is required and must be a valid email address';
	}
	if(!Zend_Filter::isAlnum($values['password']) || (strlen($values['password']) < 6) || (strlen($values['password']) > 12)) {
		$errors[] = 'Password must consist of only letters and numbers and must be between 6 and 12 characters';
	}
	return $errors;
}

Check it out, in action. And that’s about it – pretty simple, huh?

You can download: