YII+DWZ,制作了DwzActiveForm,用于自动把Yii的rules与dwz已整合的validate结合

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。

发表评论