Location: PHPKode > scripts > Combo Validation > combo-validation/validationV1.class.inc.php
<?php
/**
* Combo validation via PHP and Javascript
* 
* @version hide@address.com
* @author sina salek
* @package ComboValidation
* @website http://sina.salek.ws
* @company persiantools.com
* @changelog
*	+ More php5 compatibility
*	+ defaultStylesEnabled=false for customizing all the styles
* 	+ in firefox when form defines in non w3c way, firefox cann't find the fields inside it. it should report (reported by Akbar NasrAbadi)
* 	+ getElementsByName() issue with multiRadioBoxes and multiCheckBoxes solved 
* 	+ supporting for new type "array"
* 	+ optimizing getFormFieldObject() for large forms
* 	+ if formName does not define, it will for the fields in the whole document
* 	+ support finding the field value via only field name without pattern name
* 	+ tested with PHP 4.x and PHP 5.2.x
* 	+ completely tested with IE 6.x,7.x , Firefox 2.x , Opera 9.x , Safari 3.x
* 	+ ajax support via comppletely overriding object display or validation function
* 	+ custom field type
* 	+ customizing error messages
* 	+ override display function
* 	+ custom new display modes
* 	+ overriding or extending validation functions (validate,validateAfter,validateBefore)
* 	+ limited custom validation for fields which have need regular validations like notEmpty and also some more
* 	+ chain of commands pattern support for javascript and php
* 	+ validate fields with regular expression (javascript & php)
* 
* @todo
* 	
* 	- better error reporting
* 	- validation for fields and parameters
* 	- making it jquery compatible
* 	- validation should work with multipy forms in one page (by adding formName item to each fieldInfo)
* 	- single javascript class in webpage with multiply usage,validation instances should be connected
* 	- special methods for ease of validation via Ajax
* 	- support three type of messages , warning , information , error
* 	- compress javascripts
*/


define ('CMF_ValidationV1_Ok',true);
define ('CMF_ValidationV1_Error',2);
define ('CMF_ValidationV1_Is_Not_Valid_Email',3);
define ('CMF_ValidationV1_Is_Not_Valid_Url',4);
define ('CMF_ValidationV1_Is_Not_Number',5);
define ('CMF_ValidationV1_Is_Not_Within_Range',6);
define ('CMF_ValidationV1_Is_Not_Within_Count_Range',7);
define ('CMF_ValidationV1_Is_Empty',8);
define ('CMF_ValidationV1_Is_Not_Selected',9);
define ('CMF_ValidationV1_Is_Not_Within_Length_Range',10);
define ('CMF_ValidationV1_Is_Not_String',11);
define ('CMF_ValidationV1_Is_Not_Match_With_Pattern',12);
define ('CMF_ValidationV1_Field_Does_No_Exists',13);
define ('CMF_ValidationV1_Password_And_Its_Confirmation_Are_Not_Same',14);

/**
* This class is meant to validate HTML forms via PHP and also Javascript  in the simplest possible way. 
* all you need to do is to create an array of form fields information with require parameters and then call few methods.
* @package ComboValidation
*/
class cmfcValidationV1 extends cmfcClassesCore {
	/**
	* javascript class and function name prefix for preventing
	* duplication
	* @var string
	*/
	var $_prefix='cmf';
	/**
	* name of the form which contains fields
    * <code> 
    * <form name="myForm"....
    * </code>
    * var string
	*/
	var $_formName;
    /**
    * Name of the javascrip variable that will contain ComboValidation class instance
    * @var string
    */
	var $_jsInstanceName='myValidation';
	/**
	* 
	* @var boolean
	*/
	var $_defaultStylesEnabled=true;
	/**
	* 
	* @var boolean
	*/
	var $_prepareOnCall=true;
	/**
	* for multilingual website you can change this messages easily
	* @notice do not include following code into class initializing array, because messages name (definitions)
	*   define after object initializing
	*/
	var $_messagesValue=array(
		CMF_ValidationV1_Error=>'Unknown error',
		CMF_ValidationV1_Is_Not_Valid_Email=>'"__value__" in __title__ is not valid email',
		CMF_ValidationV1_Is_Not_Valid_Url=>'"__value__" in __title__ is not valid url',
		CMF_ValidationV1_Is_Not_Number=>'"__value__" in __title__ is not number',
		CMF_ValidationV1_Is_Not_Within_Range=>'"__value__" of __title__ is not within this range (__min__,__max__)',
		CMF_ValidationV1_Is_Not_Within_Count_Range=>'"__value__" of __title__ is not within this count range (__min__,__max__)',
		CMF_ValidationV1_Is_Empty=>'__title__ value should not be empty',
		CMF_ValidationV1_Is_Not_Selected=>'__title__ is not selected',
		CMF_ValidationV1_Is_Not_Within_Length_Range=>'"__value__" of __title__ is not within this length range (__min__,__max__)',
		CMF_ValidationV1_Is_Not_String=>'__title__ is not string',
		CMF_ValidationV1_Is_Not_Match_With_Pattern=>'__title__ is not match with __desc__',
		CMF_ValidationV1_Field_Does_No_Exists=>'__title__ field "__fieldName__" does not exists',
		CMF_ValidationV1_Password_And_Its_Confirmation_Are_Not_Same=>"__title__ field and its confirmation are not the same",
		CMF_ValidationV1_Is_Not_Array=>'__title__ is not array'
	);
    /**
    * An array including occured errors
    * @var array
    */
	var $_errorsStack=array();
	/**
    * Possible values : alert, div, pageCenterDiv, formCenterDiv, nearFields, customizedDiv
	* @var string 
	*/
	var $_displayMethod='alert';
	/**
	* Details information about displayMethod settings
	* @var array
	*/
	var $_displayMethodOptions=array();

	/**
	* All of the require information about fields
	* @var array
	*/
	var $_fieldsInfo=array(
		'email'=>array(
			'name'=>'row[email]',
			'title'=>'Email',
			'type'=>'email',
			/**
			* id of the elements which is responsible for showing event of the specific 
			* form field.
			* if will be used if you set errorDisplayMethod to 'nearFields'
			*/
			'jsMessageBoardId'=>'',
			'param'=>array(
				'min'=>0,
				'max'=>5,
				'notEmpty'=>true
			)
		),
	);
	
	/**
	* Custom field types array
    * @var array
	*/
	var $_fieldTypesInfo=array(
		'age'=>array(
			/**
			* methodname($obj,$fieldsValues,$fieldInfo,$patternName,$a,$b,$c)
			* array('function'=>array(&$object,'methodname','parameters'=>array($a,$b,$c))
			*/
			'validationHandler'=>array(
				'function'=>'', //name of the function or array of the object method array(&obj,'methodName')
				'parameters'=>array() //if your function has additional parameters
			),
			/**
			* methodname(obj,fieldsValue,fieldInfo,patternName,a,b,c)
			* array('function'=>array(&$object,'methodname','parameters'=>array($a,$b,$c))
			*/
			'jsValidationHandler'=>array(
				'function'=>'', //name of the function or array of the object method array(&obj,'methodName')
				'parameters'=>array() //if your function has additional parameters
			)
		)
	);
	
	
	
	
	
	/**
    * Construction
    */
	function __construct($options) {
		$this->_fieldsInfo=array();
		$this->setOptions($options);
		//$this->addCommandHandler('validate',array(&$this,'__validate'));
	}
	
	/**
	* <code>
	* return $this->raiseError('', CMF_Language_Error_Unknown_Short_Name,
	*		PEAR_ERROR_RETURN,NULL, 
	*		array('shortName'=>$shortName));
	* </code>
	*/
	function raiseError($message = null, $code = null, $mode = null, $options = null,
                         $userinfo = null, $error_class = null, $skipmsg = false) {
		if (isset($this->_messagesValue[$code]) && empty($message))
			$message=$this->_messagesValue[$code];
			
		if (is_array($userinfo) && !empty($message) ) {
			foreach ($userinfo as $key=>$value) {
				$replacements['__'.$key.'__']=$value;
			}
			$message=cmfcString::replaceVariables($replacements,$message);
		}
		return parent::raiseError($message, $code, $mode, $options, $userinfo, $error_class, $skipmsg);
	}
	
	/**
    * Set parameters value dynamically
    * @param string //name of the property without underscore
    * @param variant //value of the property
    * @param boolean //if $value was array, setting it to true merges its previous and its new value
    */
	function setOption($name,$value,$merge=false) {
		if ($name=='fieldsInfo' and is_array($value)) {    
			foreach ($value as $k=>$v) {
				$value[$k]['name']=$k;
			}
		}
		return parent::setOption($name,$value,$merge);
	}
	
	/**
	* Convert php value to javascript
	* @param variant $var
	* @param interger $tab //number of tab chars for indent
	* @param boolean $singleLine //result as single line
	*/
	function phpParamToJs($var,$tabs = 0,$singleLine=true) {
		//if (is_string($var)) return $var;
		return cmfcHtml::phpToJavascript($var,0,true);
	}
	
	/**
	* convert php values to javascript
	* @param variant $var
	*/
	function phpParamsToJs($vars) {
		foreach ($vars as $key=>$var) {
			$vars[$key]=$this->phpParamToJs($var);
		}
		return $vars;
	}
	
	/**
	* fixing javascript incompatibility with number as array key
	* @todo : should be recursive
	* @param string $array
	*/
	function getJavascriptCompatibleArray($array) {
		$result=array();
		foreach ($array as $key=>$value) {
			$key="_$key";
			$result[$key]=$value;
		}
		
		return $result;
	}
	/**
	* @shortName getJsCAK
	* @see getJsCAK
	*/
	function getJavascriptCompatibleArrayKey($key) {
		if (is_numeric($key)) $key="_$key";
		$key=$this->phpParamToJs($key);
		return $key;
	}
	
	/**
	* short name version of getJavascriptCompatibleArrayKey()
    * @see getJavascriptCompatibleArrayKey
	*/
	function getJsCAK($key) {
		return $this->getJavascriptCompatibleArrayKey($key);
	}
	
	/**
	* validate $fieldsValues via fieldsInfo 
	* @param string $patternName //"rows[$num][columns][%s]"
	*/
	function validate($fieldsValues,$patternName=null) {
		$result1=$this->runCommand('validateBefore',array('fieldsValues'=>$fieldsValues,'patternName'=>$patternName));
		
		if ($this->hasCommandHandler('validate'))
			$result2=$this->runCommand('validate',array('fieldsValues'=>$fieldsValues,'patternName'=>$patternName));
		else
			$result2=$this->__validate(&$this,'validate',array('fieldsValues'=>$fieldsValues,'patternName'=>$patternName));
		$result3=$this->runCommand('validateAfter',array('fieldsValues'=>$fieldsValues,'patternName'=>$patternName));
		$result=cmfcPhp4::array_merge($result1,$result2,$result3);
		return $result;
	}
	
	/**
	* Validate $fieldsValues via fieldsInfo , builtin validation handler
	* @param object //commander object which is validation
    * @param string //name of the command
    * @param array //command addtional parameters
	*/
	function __validate($obj,$cmd,$params) {
		$fieldsValues=$params['fieldsValues'];
		$patternName=$params['patternName'];

		$result=array();                           
		foreach ($this->_fieldsInfo as $fieldInfo) { 
			if ($fieldInfo['disabled']==true) continue;
			if (!empty($patternName)) {
				$fieldName=sprintf($patternName,$fieldInfo['headName']);
				$fieldValue=$fieldsValues[$fieldInfo['headName']];
			} else {
				$fieldName=$fieldInfo['name'];
				$fieldValue=cmfcArray::getValueByPath($fieldsValues,cmfcHtml::fieldNameToArrayPath($fieldName));
			}
			
			$fieldInfo=$this->_fieldsInfo[$fieldName];
			$fieldTypeInfo=$this->_fieldTypesInfo[$fieldInfo['type']];
			
			$isFieldValueEmpty=false;
			if (!$this->isError($result[$fieldName])) {
				
				if (in_array($fieldInfo['type'],array('number','email','url','string','dropDownDate','checkBox','password'))) {
					if (empty($fieldValue) and $fieldValue!==0 and $fieldValue!=='0' and $fieldValue==$fieldInfo['param']['emptyValue'])
						$isFieldValueEmpty=true;

					if ($fieldInfo['param']['notEmpty']==true and $isFieldValueEmpty) {
						$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Empty, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
					}
				}
			}
			
			if (!empty($fieldInfo['likeType'])) 
				$likeType=$fieldInfo['likeType'];
			else $likeType=$fieldInfo['type'];
				
			if (!$this->isError($result[$fieldName]) and !$isFieldValueEmpty)
				switch ($likeType) {
					case 'number' :
						if (!is_numeric($fieldValue) and $fieldValue!=='') {
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Number, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
						}
						
						if (empty($result[$fieldName])) {
							if (isset($fieldInfo['param']['countMin']) or isset($fieldInfo['param']['countMax'])) {
								if (!isset($fieldInfo['param']['countMin'])) $fieldInfo['param']['countMin']='*';
								if (!isset($fieldInfo['param']['countMax'])) $fieldInfo['param']['countMax']='*';
								if ( !((strlen($fieldValue)>=$fieldInfo['param']['countMin'] or $fieldInfo['param']['countMin']=='*') and (strlen($fieldValue)<=$fieldInfo['param']['countMax'] or $fieldInfo['param']['countMax']=='*')) ) {
									$result[$fieldName]=$result[$fieldName]=$this->raiseError( '', CMF_ValidationV1_Is_Not_Within_Count_Range, PEAR_ERROR_RETURN, NULL,  array('title'=>$fieldInfo['title'],'value'=>$fieldValue,'min'=>$fieldInfo['param']['countMin'],'max'=>$fieldInfo['param']['countMax']));
								}
							}
						}
						
						if (empty($result[$fieldName])) {
							if (isset($fieldInfo['param']['min']) or isset($fieldInfo['param']['max'])) {
								if (!isset($fieldInfo['param']['min'])) $fieldInfo['param']['min']='*';
								if (!isset($fieldInfo['param']['max'])) $fieldInfo['param']['max']='*';
								if ( !(($fieldValue>=$fieldInfo['param']['min'] or $fieldInfo['param']['min']=='*') and ($fieldValue<=$fieldInfo['param']['max'] or $fieldInfo['param']['max']=='*')) ) {
									$result[$fieldName]=$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Within_Range, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue,'min'=>$fieldInfo['param']['min'],'max'=>$fieldInfo['param']['max']));
								}
							}
						}
					break;
					case 'email' :
						if (!cmfcString::isEmailValid($fieldValue) and !empty($fieldValue))
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Valid_Email, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'], 'value'=>$fieldValue));;
					break;
					case 'url' : 
						if (!cmfcUrl::isValid($fieldValue) and !empty($fieldValue)) 
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Valid_Url, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'], 'value'=>$fieldValue));
					break;
					case 'array' :
						if (!is_array($fieldValue)) {
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Array, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
						}
					break;
					case 'string' :
						if (!is_string($fieldValue)) {
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_String, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
						}
						if (empty($result[$fieldName])) {
							if (isset($fieldInfo['param']['lengthMin']) or isset($fieldInfo['param']['lengthMax'])) {
								if (!isset($fieldInfo['param']['lengthMin'])) $fieldInfo['param']['lengthMin']='*';
								if (!isset($fieldInfo['param']['lengthMax'])) $fieldInfo['param']['lengthMax']='*';
								if ( !((strlen($fieldValue)>=$fieldInfo['param']['lengthMin'] or $fieldInfo['param']['lengthMin']=='*') and (strlen($fieldValue)<=$fieldInfo['param']['lengthMax'] or $fieldInfo['param']['lengthMax']=='*')) ) {
									$result[$fieldName]=$result[$fieldName]=$this->raiseError( '', CMF_ValidationV1_Is_Not_Within_Length_Range, PEAR_ERROR_RETURN, NULL,  array('title'=>$fieldInfo['title'],'value'=>$fieldValue,'min'=>$fieldInfo['param']['lengthMin'],'max'=>$fieldInfo['param']['lengthMax']));
								}
							}
						}
						
						if (empty($result[$fieldName])) {	
							if (!empty($fieldInfo['param']['regexp'])) {
								if (!preg_match($fieldInfo['param']['regexp'],$fieldValue)) {
									$result[$fieldName]=$result[$fieldName]=$this->raiseError( '', CMF_ValidationV1_Is_Not_Match_With_Pattern, PEAR_ERROR_RETURN, NULL,  array('title'=>$fieldInfo['title'],'value'=>$fieldValue,'desc'=>$fieldInfo['param']['regexpDescription']));
								}
							}
						}
					break;
					case 'dropDownDate' : 
						if ($fieldInfo['param']['notEmpty']==true)
							if (empty($fieldValue['day']) or empty($fieldValue['month']) or empty($fieldValue['year'])) {
								$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Empty, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
							}
					break;
					case 'checkBox' :
						if (empty($fieldValue))
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Is_Not_Selected, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
					break;
					case 'password' :
						$myFieldsValues=$_POST;
						$confirmationFieldValue=cmfcArray::getValueByPath($myFieldsValues,cmfcHtml::fieldNameToArrayPath($fieldInfo['param']['confirmationFieldName']));
						if ($fieldValue!=$confirmationFieldValue)
							$result[$fieldName]=$this->raiseError('', CMF_ValidationV1_Password_And_Its_Confirmation_Are_Not_Same, PEAR_ERROR_RETURN, NULL, array('title'=>$fieldInfo['title'],'value'=>$fieldValue));
					break;
				}
				
				#--(Begin)-->custom type
				if (empty($result[$fieldName]))
			 	 	if (!empty($fieldTypeInfo['validationHandler'])) {
						$params=array(&$this,$fieldsValues,$fieldInfo,$patternName);
						$params=cmfcPhp4::array_merge($params,$fieldTypeInfo['validationHandler']['parameters']);
						$r=call_user_func_array($fieldTypeInfo['validationHandler']['function'],$params);

						if ($this->isError($r)) {
							$result[$fieldName]=$r;
						}
					}
				#--(End)-->custom type
		}
		
		return $result;
	}
	
	/**
	* print javascript object initilizing scripts
	*/
	function printJsInstance($instanceName=NULL) {
		if (is_null($instanceName)) $instanceName=$this->_jsInstanceName;
			else $this->_jsInstanceName=$instanceName;
			
		?>
		<script type="text/javascript">
		// <![CDATA[
			<?php echo $instanceName?>=new <?php echo $this->_prefix?>Validation();
			<?php echo $instanceName?>.formName="<?php echo $this->_formName?>";
			<?php echo $instanceName?>.fieldsInfo=<?php echo $this->phpParamToJs($this->_fieldsInfo,0,true)?>;
			<?php echo $instanceName?>.fieldTypesInfo=<?php echo $this->phpParamToJs($this->_fieldTypesInfo,0,true)?>;
			<?php echo $instanceName?>.displayMethod=<?php echo $this->phpParamToJs($this->_displayMethod,0,true)?>;
			<?php echo $instanceName?>.displayMethodOptions=<?php echo $this->phpParamToJs($this->_displayMethodOptions,0,true)?>;
			<?php echo $instanceName?>.defaultStylesEnabled=<?php echo $this->phpParamToJs($this->_defaultStylesEnabled,0,true)?>;
			<?php echo $instanceName?>.displayModesInfo=<?php echo $this->phpParamToJs($this->_displayModesInfo,0,true)?>;
			<?php echo $instanceName?>.messagesValue=<?php echo $this->phpParamToJs($this->getJavascriptCompatibleArray($this->_messagesValue),0,true)?>;
			<?php if ($this->_prepareOnPrint==true) {?>
				<?php echo $instanceName?>.prepare();
			<?php } else {?>
				<?php echo $instanceName?>.prepareOnLoad();
			<?php }?>
		// ]]>
		</script>
		<?php
	}
	
	/**
	* disable/enable verification of specific field on the fly in javascript mode
	*/
	function jsfChangeFieldVerificationDisabled($name,$value) {
		echo $this->_jsInstanceName.'.changeFieldVerificationDisabled('.$this->phpParamToJs($name).','.$this->phpParamToJs($value).')';
	}
	
	/**
	* assign a javascript function for handling a command
	*/
	function jsfAddCommandHandler($cmd,$handler,$parameters=null) {
		echo $this->_jsInstanceName.'.addCommandHandler('.$this->phpParamToJs($cmd).','.$this->phpParamToJs($handler).')';
	}
	
	/**
	* assign a javascript function for handling a command
	*/	
	function jsfPrependCommandHandler($cmd,$handler,$parameters=null) {
		echo $this->_jsInstanceName.'.prependCommandHandler('.$this->phpParamToJs($cmd).','.$this->phpParamToJs($handler).')';
	}

	/**
	* Run a javascript command
	*/
	function jsfRunCommand($cmd,$params=array()) {
		echo $this->_jsInstanceName.'.runCommand('.$this->phpParamToJs($cmd).','.$this->phpParamToJs($params).')';
	}
	
	/**
	* Disable/enable verification of specific field on the fly in php mode
	*/
	function changeFieldVerificationDisabled($name,$value) {
		$this->_fieldsInfo[$name]=$value;
	}

	/**
	* @param string|object //form name or instance of a form tag
	*/
	function printJsHookFormFields($form) {?>
		<script type="text/javascript">
			<?php echo $this->_jsInstanceName?>.hookFormFields(<?php echo $form?>);
		</script>
		<?php
	}

	
	/**
	* print the whole javascritp class
	*/
	function printJsClass() {
	?>
		<script type="text/javascript">
		<?php //ob_start();?>
		// <![CDATA[
		
		function <?php echo $this->_prefix?>Validation() {
				this.formName;
				this.formObj;
				this.fieldsInfo=new Array();
				this.fieldTypesInfo=new Array();
				this.messagesValue=new Array();
				
				this.message;
				this.displayMethod='alert';
				this.displayMethodOptions;
				this.displayModesInfo;
				this.commandHandlers=new Array();
				
				var _this=this;
				
				this.callUserFunction=function (name,params) {
					if (params) {
						var paramsStr='';
						var comma='';
						for (i in params) {
							paramsStr+=comma+'params["'+i+'"]';
							comma=',';
						}
					}

					if (typeof(name)=='string') {
						var s=name+'('+paramsStr+')';
						var result=eval(s);
					} else if (typeof(name)=='array' || typeof(name)=='object') {
						var s='name[0].'+name[1]+'('+paramsStr+')';
						var result=eval(s);
					}
					
					return result;
				}
				
				this.isEmailValid=function (email) {
					var str=email;
					var filter=/^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
					if (filter.test(str))
						testresults=true;
					else {
						testresults=false;
					}
					return (testresults)
				}
				
				this.addCommandHandler=function (cmd, commandHandler,parameters) {
					if (!_this.commandHandlers[cmd]) _this.commandHandlers[cmd]=new Array();
					_this.commandHandlers[cmd].push(commandHandler);
				}
				
				this.prependCommandHandler=function (cmd, commandHandler,parameters) {
					if (!_this.commandHandlers[cmd]) _this.commandHandlers[cmd]=new Array();
					_this.commandHandlers[cmd].unshift(commandHandler);
				}
				
				this.runCommand=function (cmd,params) {
					if (_this.commandHandlers[cmd])
					for (i in _this.commandHandlers[cmd]) {
						var commandHandler=_this.commandHandlers[cmd][i];
						if (typeof(commandHandler)!='function') {
							return _this.callUserFunction(commandHandler,{'obj':_this,'cmd':cmd,'params':params});
						}
					}
				}
				
				this.isUrlValid=function (value){
					var str=value;
					var filter=/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i;
					if (filter.test(str))
						testresults=true;
					else {
						testresults=false;
					}
					return (testresults);

					/*
					var urlregex = new RegExp("^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}[0-9A-Za-z\.\-]*\.[0-9A-Za-z\.\-]*$");
					if(urlregex.test(value)) {
						return true;
					} return false;
					*/
				}
				
				this.isNumeric=function (value) {
					if ((isNaN(value)) || (value.length == 0))
						return false;
					return true;
				}
				
				this.isString=function (value) {
					if (typeof(value)=='string')
						return true;
					return false;
				}
				
				this.isEmpty=function(value) {
					if (!value) return true;
					return false;
				}
				
				
				this.getAllElements=function(docObj) {
					var all = docObj.all ? docObj.all : docObj.getElementsByTagName('*');
					return all;
				}
				
				
				this.getElementsByName=function (docObj,name) 
				{
					if (!_this.elementsByNameCache) {
						_this.elementsByNameCache=new Array();
						
						if (docObj==null) {docObj=document;}
						var all = docObj.all ? docObj.all : docObj.getElementsByTagName('*');
						var elements = new Array();
						var n=0;
						for (var e = 0; e < all.length; e++) {
							var elm=all[e];

							if (elm.name) {
								if (typeof(_this.elementsByNameCache[elm.name])!='array' && typeof(_this.elementsByNameCache[elm.name])!='object') {
									_this.elementsByNameCache[elm.name]=new Array();
									_this.elementsByNameCache[elm.name][0]=elm;
								} else {
									_this.elementsByNameCache[elm.name][_this.elementsByNameCache[elm.name].length+1]=elm;
								}
								//alert(elm.name+':'+_this.elementsByNameCache[elm.name].length);
							}
						}
					}
                   
					var elements=_this.elementsByNameCache[name];
					
					
					if (elements)
						return elements;
					else
						return false;
				}
				
				/**
				* replace a variable 
				* @param needle string
				* @param _replace string
				* @param text string
				*/
				this.strReplace=function (needle, _replace, text) {
					//return text.split(needle).join(replacement);
					if (text.indexOf(needle)!=-1) {
						//alert('needle : '+needle+' , replace : '+_replace+' , text : '+text);
						text = text.replace(needle, _replace);
						//alert('needle : '+needle+' , replace : '+_replace+' , text : '+text);
					}
					
					return text;
				}
				
				/**
				* replace variables with replacements in string
				* @param replacements array
				* @param text string
				*/
				this.replaceVariables=function (replacements,text) {
					for (key in replacements) {
						value=replacements[key];
						text=_this.strReplace(key,value,text);
						
					}
					return text;
				}
				
				/**
				* 
				*/
				this.raiseError=function (message, code , mode , options , userinfo , error_class , skipmsg ) {

					if (_this.messagesValue[code] && !message)
						message=_this.messagesValue[code];

					if (userinfo && typeof(userinfo)!='string' && message ) {
						var replacements=new Array();
						for (key in userinfo) {
							value=userinfo[key];
							replacements['__'+key+'__']=value;
						}
						message=_this.replaceVariables(replacements,message);
						
					}
					if (!message) message=' No error message defined!! ';
					return message;
				}
				
			    /**
			    * get field object
			    */
				this.getFormFieldObject=function (name,parent) {
					if (!parent) parent=document;

					var elms=_this.getElementsByName(parent,name);
					
					if (elms) {
						var x=0;
						var found=false;
						var foundIndex=0;
						for (var x = 0; x < elms.length; x++) {
							if (typeof(elms[x])=='object') {
							
								if (elms[x].type=='radio') {
									if (elms[x].checked)
										if (elms[x].checked==true)
											foundIndex=x;
								}

								if (elms[x].type=='checkbox') {
									if (elms[x].checked)
										if (elms[x].checked==true)
											foundIndex=x;
								}
							}
							
						}						
						return elms[foundIndex];
					}
					return false;
				}
				
				this.pause=function (millis) {
					var date = new Date();
					var curDate = null;

					do { curDate = new Date(); }
					while(curDate-date < millis)
				}
				
				/**
				* disable or enable field validation dynamically
				*/
				this.changeFieldVerificationDisabled=function (name,value) {
					if (_this.fieldsInfo[name])
						_this.fieldsInfo[name]['disabled']=value;
				}
				
				
				/**
				* validate field according to fieldInfo
				* @param fieldInfo array //contains require info for validating field
				*/
				this.validateField=function (fieldInfo) {
					//var fieldInfo=params['fieldInfo'];
					//var _this=obj;
					var message='';
					var fieldTypeInfo;
					var fieldValue;
					
					if (fieldInfo['type']!='')
						if (_this.fieldTypesInfo[fieldInfo['type']])
							fieldTypeInfo=_this.fieldTypesInfo[fieldInfo['type']];
					
					if (fieldInfo['disabled']==true) return true;
					
					var likeType;
					var type=fieldInfo['type'];

					if (fieldInfo['likeType'])
						likeType=fieldInfo['likeType'];
					else
						likeType=fieldInfo['type'];

					if (likeType=='number' || likeType=='string' || likeType=='url' || likeType=='email' || likeType=='checkBox' || 
							type=='number' || type=='string' || type=='url' || type=='email' || type=='checkBox' || type=='password') {
						var fieldObj=_this.getFormFieldObject(fieldInfo['name'],_this.formObj);
						      
						if (fieldObj)
							fieldValue=fieldObj.value;
						else {
							message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Field_Does_No_Exists)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'fieldName':fieldInfo['name']} );
						}
					}
                    
					if (!message)
					switch (likeType) {
						case 'number' : 
							var isFieldValueEmpty=false;
							if (_this.isEmpty(fieldValue) && fieldObj && (fieldValue==fieldInfo['param']['emptyValue'] || fieldInfo['param']['emptyValue']==null))
								isFieldValueEmpty=true;
							if (fieldInfo['param']['notEmpty']==true && isFieldValueEmpty) {
							//if (fieldInfo['param']['notEmpty']==true && _this.isEmpty(fieldValue) && fieldObj && fieldValue!=fieldInfo['param']['emptyValue']) {
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
							
							if(!isFieldValueEmpty) {
								if (message=='') {
									 if (!_this.isNumeric(fieldValue) && fieldValue!='')
										message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Number)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue} );
								}
								if (message=='') {
									if (fieldInfo['param']['countMin'] || fieldInfo['param']['countMax']) {
										if (!fieldInfo['param']['countMin']) fieldInfo['param']['countMin']='*';
										if (!fieldInfo['param']['countMax']) fieldInfo['param']['countMax']='*';
									
										if ( !((fieldValue.length>=fieldInfo['param']['countMin'] || fieldInfo['param']['countMin']=='*') && (fieldValue.length<=fieldInfo['param']['countMax'] || fieldInfo['param']['countMax']=='*')) )
											message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Within_Count_Range)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue,'min':fieldInfo['param']['countMin'], 'max':fieldInfo['param']['countMax']} );
									}
								}
								if (message=='') {
									if (fieldInfo['param']['min'] || fieldInfo['param']['max']) {
										if (!fieldInfo['param']['min']) fieldInfo['param']['min']='*';
										if (!fieldInfo['param']['max']) fieldInfo['param']['max']='*';
									
										if ( !((fieldValue>=fieldInfo['param']['min'] || fieldInfo['param']['min']=='*') && (fieldValue<=fieldInfo['param']['max'] || fieldInfo['param']['max']=='*')) )
											message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Within_Range)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue,'min':fieldInfo['param']['min'], 'max':fieldInfo['param']['max']} );
									}
								}
							}
						break;
						case 'email' :
							if (fieldInfo['param']['notEmpty']==true && _this.isEmpty(fieldValue) && fieldObj) {
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							} 
							if (!message && !_this.isEmpty(fieldValue))
								if (!_this.isEmailValid(fieldValue)) message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Valid_Email)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue} );
						break;
						case 'url' :
							if (fieldInfo['param']['notEmpty']==true && _this.isEmpty(fieldValue) && fieldObj) {
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							} 
							if (!message && !_this.isEmpty(fieldValue))
								if (!_this.isUrlValid(fieldValue)) message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Valid_Url)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue} );
						break;
						case 'dropDownDate' :
							if (fieldInfo['param']['notEmpty']==true) {
								var dayObj=_this.getFormFieldObject(fieldInfo['name']+'[day]', _this.formObj);
								var monthObj=_this.getFormFieldObject(fieldInfo['name']+'[month]', _this.formObj);
								var yearObj=_this.getFormFieldObject(fieldInfo['name']+'[year]', _this.formObj);

								if (_this.isEmpty(dayObj.value) || _this.isEmpty(monthObj.value) || _this.isEmpty(yearObj.value))
									message=_this.raiseError('', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
						break;
						case 'checkBox' :
							fieldValue=fieldObj.checked;
							if (fieldInfo['param']['notEmpty']==true && fieldValue!=true && fieldObj)
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Selected)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
						break;
						case 'password' :
							if (fieldInfo['param']['notEmpty']==true && _this.isEmpty(fieldValue) && fieldObj) {
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
							
							if (!message) {
								var confirmationFieldObj=_this.getFormFieldObject(fieldInfo['param']['confirmationFieldName'], _this.formObj);
								var confirmationFieldValue=confirmationFieldObj.value;
								if (fieldValue!=confirmationFieldValue)
									message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Password_And_Its_Confirmation_Are_Not_Same)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
						break;
						case 'string' :
							if (fieldInfo['param']['notEmpty']==true && _this.isEmpty(fieldValue) && fieldObj) {
								message=_this.raiseError( '', <?php echo $this->getJsCAK(CMF_ValidationV1_Is_Empty)?>, 'ERROR_RETURN', null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
							
							if (message=='') {
								 if (!_this.isString(fieldValue))
									message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_String)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue} );
							}
							
							if (message=='') {
								if (fieldInfo['param']['lengthMin'] || fieldInfo['param']['lengthMax']) {
									if (!fieldInfo['param']['lengthMin']) fieldInfo['param']['lengthMin']='*';
									if (!fieldInfo['param']['lengthMax']) fieldInfo['param']['lengthMax']='*';
								
									if ( !((fieldValue.length>=fieldInfo['param']['lengthMin'] || fieldInfo['param']['lengthMin']=='*') && (fieldValue.length<=fieldInfo['param']['lengthMax'] || fieldInfo['param']['lengthMax']=='*')) )
										message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Within_Length_Range)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue,'min':fieldInfo['param']['lengthMin'], 'max':fieldInfo['param']['lengthMax']} );
								}
							}
							
							if (message=='') {
								if (fieldInfo['param']['jsRegexp']) {
									var myregexp = eval(fieldInfo['param']['jsRegexp']);
									
									if (myregexp.exec(fieldValue)==null)
										message=_this.raiseError('',<?php echo $this->getJsCAK(CMF_ValidationV1_Is_Not_Match_With_Pattern)?>,'ERROR_RETURN',null, {'title':fieldInfo['title'],'value':fieldValue,'desc':fieldInfo['param']['regexpDescription']} );
								}
							}
						break;
					}
					//--(Begin)-->custom type
					if (message=='') {
						if (fieldTypeInfo)
							if (fieldTypeInfo['jsValidationHandler']!='') {
								var s=fieldTypeInfo['jsValidationHandler']['function']+'('+'_this,fieldInfo,fieldValue'+')';
								message=eval(s);
							}
					}
					//--(End)-->custom type							
					
					if (message!=null && message!='' && message) {
						return message;
					}
					return false;
				}
				
				/**
				* display generated messages by validate form in various ways 
				* @param fieldsInfo array
				* @param messsages array //generated messages
				*/
				this.displayError=function (fieldsInfo,messages) {
					var result=false;

					if (_this.displayMethod=='alert' && messages!==false) {
						var messagesStr='';
						for (key in messages) if (typeof(messages[key])!='function') {
							//alert(key+'|'+messages[key]+'|');
							fieldInfo=_this.fieldsInfo[key];
							if (messages[key]!='') 
								messagesStr+=messages[key]+'\n';
						}
						//if (messagesStr!='')
						alert(messagesStr);
						result=true;
					}
					
					if (_this.displayMethod=='div') {
						var messagesStr='';
						messagesStr='<ul>';
						for (key in messages) if (typeof(messages[key])!='function') {
							fieldInfo=_this.fieldsInfo[key];
							if (messages[key])
								messagesStr+='<li>'+messages[key]+'</li>';
						}
						messagesStr+='</ul>';
						var container=document.getElementById(_this.displayMethodOptions['id']);
						container.innerHTML=messagesStr;
						result=true;
					}
					
					if (_this.displayMethod=='pageCenterDiv' || _this.displayMethod=='formCenterDiv') {
						if (_this.displayMethod=='formCenterDiv') {
							var divContainer=_this.formObj;
						}
						
						var messagesStr='';
						messagesStr='<ul>';
						for (key in messages) if (typeof(messages[key])!='function') {
							fieldInfo=_this.fieldsInfo[key];
							if (messages[key]) 
								messagesStr+='<li>'+messages[key]+'</li>';
						}
						messagesStr+='</ul>';
						messagesStr+='<div style="text-align:center;padding:4px"><a href="javascript:void(0)" onclick="this.parentNode.parentNode.style.display=\'none\'">[OK]</a></div>';
						
						if (!divContainer)
							var divContainer=document.body;
						
						if (!_this.centerDiv) {
							_this.centerDiv = document.createElement('div');
							//newdiv.setAttribute('id', id);
							_this.centerDiv.className='<?php echo $this->_prefix?>ErrorMessageBoard';
							_this.centerDiv.style.position='absolute';
							if (_this.defaultStylesEnabled==true) {
								_this.centerDiv.style.background="white";
								_this.centerDiv.style.border="1px solid";
							}
							document.body.appendChild(_this.centerDiv );
						}
						
						_this.centerDiv.innerHTML=messagesStr;
						_this.centerDiv.style.display='';

						if (divContainer==document.body) {
							var scrollTop=typeof(window.pageYOffset)!='undefined' ? window.pageYOffset : document.documentElement.scrollTop;
							var scrollLeft=typeof(window.pageYOffset)!='undefined' ? window.pageXOffset : document.documentElement.scrollLeft;
						} else {
							var scrollTop=0;
							var scrollLeft=0;
						}
						var IpopTop = (divContainer.clientHeight - _this.centerDiv.offsetHeight) / 2 ;
						var IpopLeft = (divContainer.clientWidth - _this.centerDiv.offsetWidth) / 2;

						_this.centerDiv.style.left=IpopLeft + scrollLeft+'px';
						_this.centerDiv.style.top=IpopTop + scrollTop+'px';
						
						//this.pause(1000);
						result=true;
					}
					
					if (_this.displayMethod=='nearFields') {
						for (key in messages) if (typeof(messages[key])!='function') {
							var message=messages[key];
							var messageBoard=null;
							
							var fieldInfo=_this.fieldsInfo[key];
							if (fieldInfo['jsMessageBoardObject']) {
								messageBoard=fieldInfo['jsMessageBoardObject'];
							} else if(fieldInfo['jsMessageBoardId']) {
								messageBoard=document.getElementById(fieldInfo['jsMessageBoardId']);
								fieldInfo['jsMessageBoardObject']=messageBoard;
								
								if (!fieldInfo['jsMessageBoardObject'])
									alert('Message board "'+fieldInfo['jsMessageBoardId']+'" of field "'+fieldInfo['name']+'" id does not exists');
							}
							
							if (!messageBoard) {
								var fieldObj=_this.getFormFieldObject(fieldInfo['name'],_this.formObj);
								var messageBoard = document.createElement('div');
								messageBoard.className='<?php echo $this->_prefix?>ErrorMessageBoard';

								fieldInfo['jsMessageBoardId']=messageBoard.id=fieldInfo['name']+'MsgBoard';
								if (_this.defaultStylesEnabled==true) {
									messageBoard.style.background="white";
									messageBoard.style.border="1px solid";
								}
								fieldObj.parentNode.appendChild(messageBoard);
								_this.fieldsInfo[key]['jsMessageBoardObject']=messageBoard;
							} else {
								
							}

							if (message) {
								messageBoard.innerHTML=message;
								messageBoard.style.display='';
							} else {
								messageBoard.style.display='none';
							}
						}
						result=true;
					}
					
					
					//--(Begin)-->custom display mode
					if (result==false) {
						if (_this.displayModesInfo) {
							var displayModeInfo=_this.displayModesInfo[_this.displayMethod];
							
							if (displayModeInfo['jsHandler']) {
								var s=displayModeInfo['jsHandler']['function']+'('+'_this,fieldsInfo,messages,_this.displayMethodOptions'+')';
								eval(s);
							}
						}
						result=true;
					}
					//--(End)-->custom display mode
					
					return result;
				}
				
				/**
				* merge 2 dimensional arrays
				*/
				this.arrayMerge=function (array1,array2) {
					var rArray=array1;
					for (i in array2) {
						rArray[i]=array2[i];
					}
					return rArray;
				}
			 	
			 	/**
			 	* trigger after submiting form
			 	*/
				this.onFormSubmit=function (e) {
					var allMessages=new Array();
					var isValid=true;
					var messages;
					messages=_this.runCommand('validateBefore',{'fieldsInfo':_this.fieldsInfo});
					if (messages!==true && messages) {
						allMessages=_this.arrayMerge(allMessages,messages);
						isValid=true;
					}
					messages=_this.runCommand('validate',{'fieldsInfo':_this.fieldsInfo});
					if (messages!==true && messages) {
						allMessages=_this.arrayMerge(allMessages,messages);
						isValid=false;
					}
					messages=_this.runCommand('validateAfter',{'fieldsInfo':_this.fieldsInfo});
					if (messages!==true && messages) {
						allMessages=_this.arrayMerge(allMessages,messages);
						isValid=false;
					}

					
					if (!isValid) {
						_this.displayError(_this.fieldsInfo,allMessages);
						return false;
					} else {
						return true;
					}
				}
				
				/**
				* assign built in function to handle form validation
				*/
				this.addCommandHandler('validate',[_this,'validateForm']);
				
				/**
				* built in form validation function
				*/
				this.validateForm=function (obj,cmd,params) {
					var messages=new Array();
					var fieldInfo;
					var fieldObj;
					var key;
					_this.elementsByNameCache='';
					var isCompletelyValid=true;
					
					for (key in _this.fieldsInfo) {
						fieldInfo= _this.fieldsInfo[key];

						try {
							messages[key]=_this.validateField(fieldInfo)
							
							if (messages[key]!==false)
								isCompletelyValid=false;
						} catch(err) {
							messages[key]='Error Description : '+err.description;
							isCompletelyValid=false;
						}
					}

					if (isCompletelyValid===false) return messages;
					return true;
				}
				
				/**
				* assign object validation methods to handle form validation
				*/
				this.prepare=function () {
					if (_this.formName!='' && _this.formName!=null) {
						
						_this.formObj=document.getElementsByName(_this.formName)[0];
						if (!_this.formObj) {
							alert('cmfcValidation : the specified form does not exists!');
						} else {
							var obj=_this.getAllElements(_this.formObj);
							if (!obj.length>0) alert('cmfcValidation : the specified form does not have any field (The form tag might not be W3C valid)!');
						}
						_this.formObj.onsubmit=function () { return _this.onFormSubmit()};
					}
				}
				
				/**
				* do the preapre on page load
				*/
				this.prepareOnLoad=function () {
					if (window.addEventListener)
						window.addEventListener("load", this.prepare, false)
					else if (window.attachEvent)
						window.attachEvent("onload", this.prepare)
				}
		}
		
		
       
		// ]]>
		<?php
		//$js=ob_get_contents();
		//$js=str_replace(array("\n","\r","\t"),'',$js);
		//ob_end_clean();
		//echo $js;
		?>
		</script>
	<?php
	}
}
Return current item: Combo Validation