Browse | Submit New Snippet | Create Package

 

Simple Client-Side Pure Javascript Form Validation

Type:
Sample Code (HOWTO)
Category:
HTML Manipulation
License:
GNU General Public License
Language:
PHP
 
Description:
This snippet is based on http://wiki.cakephp.org/tutorials:alternate_advanced_validation

I needed a simple way to automate the creation of a Javascript form validator to reduce the number of round-trips to the server. I tried the one at the link (given above), but it gave me some weird errors regarding the app_model.php! So, I decided to hack it up a little bit to suit my needs.

Versions Of This Snippet::

Akshay Patel
Snippet ID Download Version Date Posted Author Delete
1800.012006-07-16 09:24Akshay Patel

Download a raw-text version of this code by clicking on "Download Version"

 


Latest Snippet Version: :0.01

Step 1: Create a new Helper called validators.php and place it in /app/views/helpers/

- begin /app/views/helpers/validators.php -

<?php

	/**
  	 * Code "taken" from http://wiki.cakephp.org/tutorials:alternate_advanced_validation
  	 */

	class ValidatorsHelper extends Helper {
		
		function javascriptErrors($modelNames) {
			if(!is_array($modelNames)) {
				$modelNames = array($modelNames);
			}
			$scriptTags  	 = "function validate(form) {\n";
			$scriptTags		.= "	errors = new Array;\n";
			$scriptTags		.= "	tags = form.elements;\n";
			$scriptTags		.= "	for(i = 0; i < tags.length; i++) {\n";
			
			foreach($modelNames as $modelName) {
				$model = new $modelName();
			
				foreach ($model->validators as $field_name => $validators)
				{
					foreach($validators as $validator) {
						$scriptTags	.= "		if(tags[i].name != null && tags[i].name == 'data[" . $model->name . "][" . $field_name . "]') {\n";
						$scriptTags .= "			if(!tags[i].value.match(" . $validator['expression'] . ")) {\n";
						$scriptTags .= "				errors.push('" . $validator['message'] . "');\n";
						$scriptTags .= "			}\n";
						$scriptTags .= "		}\n";
	
					}
				}
			}
			$scriptTags 	.= "	}\n";			
			$scriptTags 	.= "	return errors;\n";
			$scriptTags 	.= "}\n";
			
			return $scriptTags;
		}
	}
?>

- end -

Step 2: In your Model, you need to add a new variable called $validators which should be in the shown format. Please note that you still need to include var $validate separately for Cake to authenticate the data before storing it in the database, which is very important for security reasons. $validators is only used to generate the Javascript code which verifies the form data at the client end. 

The code shown here is for a "generic" User Model.

- begin /app/models/user.php -

<?php 
	class User extends AppModel
	{	
		var $name = 'User';
		var $useDbConfig = 'userauth';
		
		var $validate = array(
		
			'username' => VALID_NOT_EMPTY,
			'username' => '/[a-z0-9\_\-]{3,}$/i',
			'pass' => VALID_NOT_EMPTY,
			'first_name' => VALID_NOT_EMPTY
		
		);
		
		var $validators = array(
			
			'username' => array(
				array('expression' => VALID_NOT_EMPTY, 'message' => "Please choose a username"),
				array('expression' => '/[a-z0-9\_\-]{3,}$/i', 'message' => "Please use alphanumeric symbols only")
			),
			
			'pass' => array(
				array('expression' => VALID_NOT_EMPTY, 'message' => 'Please enter a password')
			),
			
			'first_name' => array(
				array('expression' => VALID_NOT_EMPTY, 'message' => 'Please enter your first name')
			)
			
		);
		
	}
 ?>

- end -

Note that you can have multiple validators for a single form element. Sweet eh?

Step 3: Don't forget to include the 'validators' Helper in your Controller like so: var $helpers = array('blah', 'validators');

Step 4: Finally, include the following code in all your Views for which you want Javascript form validation of a particular model. Notice the use of $validators->javascriptErrors('modelName') which dynamically generates the required JS code.

- begin /app/views/users/register.thtml -

<SCRIPT language="Javascript">
<?php echo $validators->javascriptErrors('User'); ?>
function validateForm(form) {
	
	var errors = validate(form);
	
	if(errors.length == 0) {
		return true;
	} else {
		var str = "";
		for(i = 0; i < errors.length; i++) {
			str += errors[i] + "\n";
		}
		alert (str); // You can format variable str into a nice DHTML window if you like, but I don't mind Javascript alert boxes :)
		return false;
	}
}

</SCRIPT>

<form action = "<?php echo $html->url('/users/register'); ?>" method = "post" onSubmit = "return validateForm(this)">

.
.
.

</form>

- end - 

That's it! You can use this simple, but powerful, idea in a variety of ways! I hope someone finds this useful. Cheers!
		

Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..