YII自带validate.js的验证,但我细读源码,发现其规则主要是提交后返回的,而DWZ整合validate.js是直接在提交时客户端验证,更为方便有效率。
model中定义的rules已经把属性的要求都写清楚,如果再为了validate又在view里手写一次,实在是麻烦,所以我有了写DwzActiveForm的想法。
1、在Yii源码中找到CActiveForm,复制出新的Widget命名DwzActiveForm放在ext.dwz中。
2、自定义一个方法addValidateAttr($model,$attribute,&$htmlOptions),较简单的源码如下:
private static function addValidateAttr($model,$attribute,&$htmlOptions){ $rules=$model->rules(); foreach($rules as $rule){ if($rule[1]=='required') continue; $attrArr=explode(',', str_replace(' ','',$rule[0])); if(in_array($attribute, $attrArr)){ if($rule[1]=='numerical'){ if(isset($rule['integerOnly'])){ if(isset($htmlOptions['class'])) $htmlOptions['class'].=' digits'; else $htmlOptions['class']='digits'; }else{ if(isset($htmlOptions['class'])) $htmlOptions['class'].=' number'; else $htmlOptions['class']='number'; } if(isset($rule['min'])) $htmlOptions['min']=$rule['min']; if(isset($rule['max'])) $htmlOptions['max']=$rule['max']; }else if($rule[1]=='length'){ if(isset($rule['min'])) $htmlOptions['minlength']=$rule['min']; if(isset($rule['max'])) $htmlOptions['maxlength']=$rule['max']; } } } } //请自行加入email,url等验证判断 //由于tooSmall等属性判断更为复杂,还需更改validate中的通知内容,我觉得这个不是必要的
3、在textField,dropDownList等所有方法内加入验证:
if($model->isAttributeRequired($attribute)){ if(isset($htmlOptions['class'])) $htmlOptions['class'].=' required'; else $htmlOptions['class']='required'; } self::addValidateAttr($model,$attribute,$htmlOptions);
4、由于DWZ默认以星号显示在文本框右上角的形式表示必填项,所以label不需要作required说明,所以可以把标签读取时采用的labelEx全改为label。
5、在form相应的view文件中采用ext.dwz.DwzActiveForm作为form的widget。