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。
