Yii提供了一个非常不错而且方便的 CActiveForm 用于辅助生成表单以及 ajax 验证。
但默认Ajax验证的处理方式存在以下几个缺点:
-
开启 validateOnChange 或 validateOnType 时,原意是只要验证变动的字段(事实上在最后显示正确或错误结果时也是只针对此字段),但在PHP端实际上是进行了全规则校验并输出,造成了一些不必要的验证,同时可能导致图片验证码容易超过 testLimit而引发问题。
-
所有的验证都通过服务端AJAX请求,哪怕只是简单的判断是否为空,长度,或一些像EMAIL/URL的正则校验,这样不仅加重服务器负担而且验证也会相对延迟。
针对以上2个问题,我编写了 EActiveForm 扩展,直接继承 CActiveForm,并在 init()以及 error()方法中插入少量代码来解决这个问题。
-
在ajax提交前会修改 $form.data(“settings”).ajaxVar 的值,把改动过的Model,attribute组合后发送给服务端,这样在PHP里可以通过 $_POST[‘attributes’][‘LoginForm’] 之类取得变动的属性列表进行验证而不是默认的全部属性。
-
覆盖 Cactiveform::init()和error() 方法,自动加入clientOptions[‘beforeValidate’]回调函数,同时针对各个属性加入 htmlOptions[‘beforeValidateAttribute’] 的回调,如果JS有错就返回 false阻止AJAX验证。
所有的JS验证规则直接从 model 的 validator 里取得并转换,所有能做的基本上做了转换,但由于CValidator的写法没有考虑这处情况,导致转换代码都偏长。
已支持的验证器包括:‘CRequiredValidator’,‘CRegularExpressionValidator’,
‘CEmailValidator’,‘CUrlValidator’,‘CCompareValidator’,
‘CStringValidator’,‘CRangeValidator’,‘CNumberValidator’,
‘CBooleanValidator’
- 当 js验证有错误时阻止表单提交,当某个字段的验证规则全部可以转换成JS验证时,如果JS验证都正确也禁止再向服务器提交AJAX验证(没必要)。
// 顺便 to Qiang, 看你也经常会来照顾中文版,呵呵
希望Yii team可以考虑把这项功能整合进官方的 ActiveForm,然后通过一个选项去控制它的开关。
具体参见该扩展主页: