Javascript voorbeeld
[code]
<script src="validator.js" type="text/javascript"></script>

<script type="text/javascript">
<!--

window.onload = function(){
	// Add the elements to the validator
	Var Validator = new jsValidator();
	Validator.elmts = {
		name: {
			validator: 'IsString',
			msg: 'This field must be a valid string'
		},
		age: {
			validator: 'IsDigit',
			msg: 'This field must be a digit'
		},
		email: {
			validator: 'IsEmail',
			msg: 'This field must be a valid e-mail'
		},
		text: {
			validator: function(value){
				// The length must be greather than 10 characters
				return value.length > 10;
			},
			msg: 'This textarea must be longer than 10 characters'
		},
		select: {
			validator: 'regex',
			regex: /^option_[0-9]+$/,
			msg: 'This value must begin with option_ and end with a number'
		}
	}
	// Fire the validator
	Validator.init();
}


// -->
</script>

[/code]

bijbehorende HTML:
[code]
<form action="#">
	<p>
		<label for="name">Name</label> 
		<input type="text" id="name" name="name_field" />
	</p>
	<p>
		<label for="age">Age</label> 
		<input type="text" id="age" name="age_field" />
	</p>
	<p>
		<label for="email">E-mail</label> 
		<input type="text" id="email" name="email_field" />
	</p>
	<p>
		<label for="text">Text</label> 
		<textarea id="text" name="description"></textarea>
	</p>
	<p>
		<label for="select">Selectfield</label> 
		<select id="select" name="select_fied">
			<option value="option_1">One</option>
			<option value="option_2">Two</option>
			<option value="option_3">Three</option>
			<option>four</option>
		</select>
	</p>
	<p class="submit">
		<input type="submit" value="Submit" />
	</p>
</form>
[/code]


Als FormHanlder gebruikt wordt:
<?php

// include the class 
include("fh3js.php"); 

// create a new FormHandler object 
$form = new Fh3_JsValidator(); 

$form->setMask(
  "  <tr>\n".
  "    <td valign='top' align='right'>%title%</td>\n".
  "    <td valign='top'>%seperator%</td>\n".
  "    <td valign='top'>%field% %help% <span id='error_%name%'>%error%</span></td>\n".
  "  </tr>\n"
);

// some fields.. (see manual for examples) 
$form->textField( "Name", "name", FH_STRING, 20, 40); 
$form->textField( "Age", "age", FH_INTEGER, 4, 40); 
$form->textField( "Functie", "functie", FH_STRING); 
$form->selectfield('Select','select',array('a',1,3,5,7),FH_DIGIT,true);
$form->textarea('text','text',FH_TEXT);
$form->textarea('text','text2',_FH_TEXT);
// button for submitting 
$form->submitButton(); 

// set the 'commit-after-form' function 
$form->onCorrect('doRun'); 

// display the form 
$form->flush(); 

// the 'commit-after-form' function 
function doRun( $data )  
{ 
    echo "Hello ". $data['name'].", you are ".$data['age'] ." years old!"; 
}

?>


Het validatie bestand:
[code]
// JS validator,Copyright (c) 2008 Arian Stolwijk, <http://aryweb.nl>, MIT Style License.

function jsValidator(){
	var Validator = {
	
		/**
		 * Version of the jsValidator
		 */
		varsion : '0.2a',
	
		/**
		 * Settings
		 */
		settings: {
			/**
			 * The standard message
			 */
			msg: 'This field is not correctly filled in',
	
			/**
			 * The style of the message, any css/javascript style (eg. color, paddingLeft)
			 */
			msgStyle: {
				paddingLeft: '5px',
				color: 'red',
				maxWidth: '300px'
			}
		},
	
	
		elmts : {
			// The Elements
		},	
		elmt: {
			// The field objects
		},
	
		/**
		 * Initializes the validator
		 */
		init: function(){
			for (var elem in this.elmts) { //for each element....
				// Skip to the next if the field doesn't extists
				if(document.getElementById(elem) == null){
					continue;
				}
				if(document.getElementById(elem).tagName == 'input' || document.getElementById(elem).tagName == 'select' || document.getElementById(elem).tagName == 'textarea'){
					continue;
				}
				this.addValidator(elem)
						
			}
		},
		
		/**
		 * Add a validator to a field, checks if the field is correct and calls the message functions
		 * @param {Object} elmt
		 */	
		addValidator: function(elem){
			this.elmt[elem] = document.getElementById(elem);
			if (typeof this.elmts[elem].validator != 'undefined'){
				if(typeof Validators[this.elmts[elem].validator] == 'function' || typeof this.elmts[elem].validator == 'function'){
					this.elmt[elem].onblur = function(){
						validator = Validator.elmts[elem].validator;
						if (Validator.elmt[elem].tagName == 'SELECT') {
							value = Validator.elmt[elem].options[Validator.elmt[elem].selectedIndex].value;
						} else {
							value = Validator.elmt[elem].value;
						}
						// Set error to true
						var error = true;
						if (validator == 'regex') {						
							// If there's a self made regex
							if (Validators.regex(value + '', Validator.elmts[elem].regex)) {
								// if the field is correct, set the error var to false
								error = false;
							}
						}else if(typeof Validator.elmts[elem].validator == 'function'){
							// There's a self made funtion
							if(Validator.elmts[elem].validator(value)){
								// if the field is correct, set the error var to false
								error = false;
							}
						}else {
							// The included validate methods
							if (Validators[validator](value + '')) {
								// if the field is correct, set the error var to false
								error = false;
							}
						}
						
						// There's been an error
						if(error == true){
							// If thers 
							if(Validator.elmts[elem].msg){
								var msg = Validator.elmts[elem].msg;
							}else{
								var msg = Validator.settings.msg;
							}
							Validator.inlineMsg(elem,msg);
						}else{
							Validator.hideMsg1(elem);
						}
					}
				}
			}
			
		},
			
		/**
		 * Build the message and calls the function to show the message
		 * 
		 * @param {Object} target
		 * @param {Object} string
		 */
		inlineMsg: function(target,string) {
			var targetdiv = document.getElementById(target);
			if (!document.getElementById('msg'+target)) {
				// Create two divs for the error message if the divs doesn't exists
				msg = document.createElement('span');
				msg.id = 'msg'+target;
				
				// give the msg div some style 
				for (var msgStyle in this.settings.msgStyle) {
					msg.style[msgStyle] = this.settings.msgStyle[msgStyle];
				}
				
				// add the msg element after the field
				targetdiv.parentNode.insertBefore(msg, targetdiv.nextSibling);
			}
			else {
				// The span elements already exists, so we can use them
				msg = document.getElementById('msg'+target);
			}
			// Put the error message into the messagecontent element
			msg.innerHTML = string;
			// Show the message
			this.showMsg(msg,target);
		},
		
		// This function calls the hideMsg method to create the same parameters like the showMsg method
		hideMsg1: function(elem){
			var elmt = document.getElementById('msg'+elem);
			this.hideMsg(elmt,elem);
		},
	
		/**
		 * You can override this function with your own function 
		 * This function shows the message
		 *
		 * @param {Object}elmt : an instance of the message element
		 * @param {String}elem : the fieldname
		 */
		showMsg: function(elmt,elem){
			if (elmt) {
				elmt.style.display = 'inline';
			}
		},
		
		
		/**
		 * This method hides the elemnt
		 * 
		 * @param {Object} elmt : an instance of the message element
		 * @param {String}elem : the fieldname
		 */
		hideMsg: function(elmt,elem) {
			if (elmt) {
				// Hide the element when the element exists
				elmt.style.display = 'none';
			}
		}
	}
	
	return Validator;
}

/**
 * An apart object for the validation objects
 */
var Validators = {

	/**
	 * Validators.regex
	 * 
	 * This method handles a custom regular expression
	 * 
	 * @param {Object} value
	 * @param {Object} regex
	 */
	regex: function(value,regex){
		return value.match(regex);
	},
	
	/**
	 * Validators.IsString()
	 *
	 * Any string that doesn't have control characters (ASCII 0 - 31) but spaces are allowed
	 *
	 * @param string value: The string to check
	 * @return bool
	*/
	IsString: function(value){
 		return value.match(/^[^\x01-\x1F]+$/);
	},

	/**
	 * Validators._IsString()
	 *
	 * Public: same as IsString, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsString: function(value)
	{
	    return value.length == 0 || this.IsString(value);
	},
	
	/**
	 * Validators.IsAlpha()
	 *
	 * Public: only letters a-z and A-Z
	 *
	 * @param string value
	 * @return bool
	 */
	IsAlpha: function(value)
	{
	    return value.match(/^[a-z]+$/i);
	},
	
	/**
	 * Validators._IsAlpha()
	 *
	 * Public: same as IsAlpha, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsAlpha: function(value)
	{
	    return value.length == 0 || this.IsAlpha(value);
	},
	
	/**
	 * Validators.IsDigit()
	 *
	 * Public: only numbers 0-9
	 *
	 * @param string value
	 * @return bool
	 */
	IsDigit: function(value)
	{
	    return value.match(/^[0-9]+$/);
	},
	
	/**
	 * Validators._IsDigit()
	 *
	 * Public: same as IsDigit, only now the value is also valid if it is empty
	 *
	 * @param string $value
	 * @return bool
	 */
	_IsDigit: function(value)
	{
	    return (value.length == 0 || this.IsDigit(value));
	},
	
	/**
	 * Validators.IsAlphaNum()
	 *
	 * Public: letters and numbers
	 *
	 * @param string value
	 * @return bool
	 */
	IsAlphaNum: function(value)
	{
	    return value.match(/^[a-z0-9]+$/i);
	},
	
	/**
	 * Validators._IsAlphaNum()
	 *
	 * Public: same as IsAlphaNum, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsAlphaNum: function(value)
	{
	    return value.length == 0 || this.IsAlphaNum(value);
	},
	
	/**
	 * Validators.IsFloat()
	 *
	 * Public: only numbers 0-9 and an optional - (minus) sign (in the beginning only)
	 *
	 * @param string value
	 * @return bool
	 */
	IsFloat: function(value)
	{
	    return value.match(/^-?([0-9]*\.?,?[0-9]+)$/);
	},
	
	/**
	 * Validators._IsFloat()
	 *
	 * Public: same as IsFloat, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsFloat: function(value){
		return value.length == 0 || this.IsFloat(value);
	},
	
	/** Validators.IsInteger()
	 *
	 * Public: only numbers 0-9 and an optional - (minus) sign (in the beginning only)
	 *
	 * @param string $value
	 * @return bool
	 */
	IsInteger: function(value)
	{
	    return value.match(/^-?[0-9]+$/);
	},
	
	/**
	 * Validators._IsInteger()
	 *
	 * Public: same as IsInteger, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsInteger: function(value)
	{
	    return value.length == 0 || this.IsInteger(value);
	},
	
	/**
	 * Validators.IsFilename()
	 *
	 * Public: a valid file name (including dots but no slashes and other forbidden characters)
	 *
	 * @param string value
	 * @return bool
	 * @TODO: This method doesn't work
	 */
	IsFilename: function(value)
	{
		return value.match(/{^[^\/\*\?\:\,]+$}/);
	},
	
	/**
	 * Validators._IsFilename()
	 *
	 * Public: same as IsFilename, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsFilename: function(value)
	{
		return value.length == 0 || this.IsFilename(value);
	},
	
	/**
	 * Validators.IsBool()
	 *
	 * Public: a boolean (case-insensitive "true"/"1" or "false"/"0")
	 *
	 * @param string value
	 * @return bool
	 */
	IsBool: function(value)
	{
	    return value.match(/^true$|^1|^false|^0$/i);
	},
	
	/**
	 * Validators._IsBool()
	 *
	 * Public: same as IsBool, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsBool: function(value)
	{
		return value.length == 0 || this.IsBool(value);
	},
	
	/**
	 * a valid variable name (letters, digits, underscore)
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsVariabele: function(value)
	{
	    if(value == '_')
	    {
	        return false;
	    }
	    else if(value.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/i))
	    {
	        return true;
	    }
	    else
	    {
	        return false;
	    }
	},
	
	/**
	 * same as IsVariabele, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsVariabele: function(value)
	{
		return value.length == 0 || this.IsVariabele(value);
	},
	
	
	/**
	 * a valid password (alphanumberic + some other characters but no spaces. Only allow ASCII 33 - 126)
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsPassword: function(value)
	{
	    return value.match(/^[\x29-\x7E]+$/);
	},
	
	/**
	 * same as IsVariabele, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsPassword: function(value)
	{
		return value.length == 0 || this.IsPassword(value);
	},

	/**
	 * check for a valid url
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsURL: function(value)
	{
	    regex = /^((http|ftp|https):\/{2})?(([0-9a-zA-Z_-]+\.)+[a-zA-Z]+)((:[0-9]+)?)((\/([0-9a-zA-Z=%\.\/_-]+)?(\?[0-9a-zA-Z%\/&=_-]+)?)?)$/;
	    return value.match(regex); 
	},
	
	/**
	 * same as IsURL, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsURL: function(value)
	{
		return value.length == 0 || this.IsURL(value);
	},
	
	/**
	 * a valid email address (only checks for valid format: xxx@xxx.xxx)
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsEmail: function(value)
	{
    	return value.match(/^[a-z0-9_\.-]+@([a-z0-9]+([\-]+[a-z0-9]+)*\.)+[a-z]{2,7}$/i);
	},
	
	/**
	 * same as IsEmail, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsEmail: function(value)
	{
		return value.length == 0 || this.IsEmail(value);
	},
			
	/**
	 * like IsString, but newline characters and tabs are allowed
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsText: function(value)
	{
	    return value.match(/^([^\x01-\x1F]|[\r\n\t])+$/);
	},
	
	/**
	 * same as IsText, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsText: function(value)
	{
			return value.length == 0|| this.IsText(value);
	},
	
	/**
	 * Check if the value does not contain any HTML
	 * 
	 * @param {string} value
	 * @return bool
	 */
	NoHTML: function(value)
	{
		return value.replace(/(<([^>]+)>)/ig,"") == value && value.length > 0;
	},
	
	/**
	 * same as NoHTML, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_NoHTML: function(value){
		return value.length == 0 || this.NoHTML(value);
	},
	
	/**
	 * is a valid dutch postcode (eg. 9999 AA)
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsPostcode: function(value)
	{
	    return value.match(/^[1-9][0-9]{3} ?[a-zA-Z]{2}$/);
	},
	
	/**
	 * same as IsPostcode, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsPostcode: function(value)
	{
	   return value.length == 0 || this.IsPostcode(value);
	},
	
	/**
	 * is a valid dutch phone-number
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsPhone: function(value)
	{
	    regex = /^[0-9]{2,4}[-]?[0-9]{6,8}$/;
	    value = value.replace(' ','');
		value = value.replace('-','');
	    return value.length == 10 && value.match(regex);
	},
	
	/**
	 * same as IsPhone, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsPhone: function(value)
	{
	    return value.length == 0 || this.IsPhone(value);
	},

	/**
	 * check if it's a valid ip adres
	 * 
	 * @param {string} value
	 * @return bool
	 */
	IsIp: function(ip )
	{
		return ip.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}:?\d*$/);
	},
	
	/**
	 * same as IsIp, only now the value is also valid if it is empty
	 *
	 * @param string value
	 * @return bool
	 */
	_IsIp: function(ip )
	{
		return value.length == 0 || this.IsIp(value);
	}
	
}

[/code]

Als je het in combinatie met formhandler gebruiken wilt, heb je deze class nodig.
Je moet dan wel eerst ook formhandler downloaden: http://www.formhandler.net

<?php

/**
 * JS validator,Copyright (c) 2008 Arian Stolwijk, <http://aryweb.nl>, MIT Style License.
 */

include_once 'fh3/class.FormHandler.php';

class Fh3_JsValidator extends FormHandler {

	protected $jsvalidator;

	public function __construct($name=null,$action=null,$extra=null,$jsvalidator=true){
		parent::FormHandler($name,$action,$extra);
		
		$this->jsvalidator = $jsvalidator;
	}

	function _setJS( $js, $isFile = false, $before = true, $eachform = false)
	{
		$this->_js[$before?0:1][$isFile?'file':'code'][] = $js;
		if(!$isFile){
			$this->_js[$before?0:1]['eachform']['code'][] = $eachform;
		}else{
			$this->_js[$before?0:1]['eachform']['file'][] = $eachform;
		}
	}
	
	
	function getJavascriptCode( $header = true )
	{
		static $return = array( 0 => false, 1 => false );;

		$s = $header ? 0 : 1;

		// if the javascript is not retrieved yet..
//		if( !$return[$s] )
//		{
			// generate the js "files" script
			$result = '';
			if( isset($this->_js[$s]['file']) && is_array($this->_js[$s]['file']) )
			{
				foreach( $this->_js[$s]['file'] as $key => $line )
				{
					if($this->_js[$s]['eachform']['file'][$key] || !$return[$s]){
						$result .= '<script language="javascript" type="text/javascript" src="'.$line.'"></script>'."\n";
					}
				}
			}
			
			// generate the other js script
			if( isset($this->_js[$s]['code']) && is_array($this->_js[$s]['code']) )
			{
				$jscode = array();
				foreach( $this->_js[$s]['code'] as $key => $code){
					if($this->_js[$s]['eachform']['code'][$key] || !$return[$s]){
						$jscode[] = $code;
					}
				}
				if(count($jscode) >= 1){
					$result .= '<script language="javascript" type="text/javascript">'."\n";
					$result .= implode($jscode);
					$result .= "</script>\n";
				}
			}
			
			$return[$s] = true;
			return $result;
//		}

		return '';
	}
	
	
	public function getFields(){
		$fields = array();
		
		foreach($this->_fields as $key => $field){
			if(!empty($key)){
				$fields[] = $key;
			}
		}
		return $fields;
	}
	
	public function getField($fldName){
		if(!empty($this->_fields[$fldName])){
			return $this->_fields[$fldName][1];
		}else{
			trigger_error('Dit veld bestaat niet');
		}
	}
	
	public function flush($return = false){
		$validator = array();
		if($this->jsvalidator){
			foreach($this->getFields() as $field){
				$field = $this->getField($field);
				
				if(!empty($field->_sValidator)){
					$validator[$field->_sName] = $field->_sValidator;
				}
			}

			$this->_setJS('validator.js',true,true);
			static $validatorI = 0;
			$js = '	var Validator'.++$validatorI.' = new jsValidator();'.PHP_EOL.
				"	Validator".$validatorI.".settings.msg = '".$this->_text( 14 )."';".PHP_EOL.
				'	Validator'.$validatorI.'.showMsg = function(elmt,elem){'.PHP_EOL.
				"		document.getElementById('error_'+elem).innerHTML = '';".PHP_EOL.
				'		if (elmt) {'.PHP_EOL.
				"			elmt.style.display = 'inline';".PHP_EOL.
				'		}'.PHP_EOL.
				'	}'.PHP_EOL.
				
				'	Validator'.$validatorI.'.hideMsg = function(elmt,elem){'.PHP_EOL.
				"		document.getElementById('error_'+elem).innerHTML = '';".PHP_EOL.
				'		if (elmt) {'.PHP_EOL.
				"			elmt.style.display = 'none';".PHP_EOL.
				'		}'.PHP_EOL.
				'	}'.PHP_EOL.
				
				'	// Add the elements to the validator'.PHP_EOL.
				'	Validator'.$validatorI.'.elmts = {'.PHP_EOL;
			
			$aantal = count($validator);
			$i=1;
			foreach($validator as $field => $fldValidator){
				$js .= '		'.$field.': {'.PHP_EOL.
					"			validator: '".$fldValidator."'".PHP_EOL.
					'		}'.($i++ < $aantal ? ',':'').PHP_EOL;
			}
			$js .= '	}'.PHP_EOL.
			'	Validator'.$validatorI.'.init();'.PHP_EOL;
			$this->_setJS($js,false,false,true);
		}
		
		parent::flush($return);
	}
	
}
?>