[扩展] EActiveForm

Yii提供了一个非常不错而且方便的 CActiveForm 用于辅助生成表单以及 ajax 验证。

但默认Ajax验证的处理方式存在以下几个缺点:

  1. 开启 validateOnChange 或 validateOnType 时,原意是只要验证变动的字段(事实上在最后显示正确或错误结果时也是只针对此字段),但在PHP端实际上是进行了全规则校验并输出,造成了一些不必要的验证,同时可能导致图片验证码容易超过 testLimit而引发问题。

  2. 所有的验证都通过服务端AJAX请求,哪怕只是简单的判断是否为空,长度,或一些像EMAIL/URL的正则校验,这样不仅加重服务器负担而且验证也会相对延迟。

针对以上2个问题,我编写了 EActiveForm 扩展,直接继承 CActiveForm,并在 init()以及 error()方法中插入少量代码来解决这个问题。

  1. 在ajax提交前会修改 $form.data(“settings”).ajaxVar 的值,把改动过的Model,attribute组合后发送给服务端,这样在PHP里可以通过 $_POST[‘attributes’][‘LoginForm’] 之类取得变动的属性列表进行验证而不是默认的全部属性。

  2. 覆盖 Cactiveform::init()和error() 方法,自动加入clientOptions[‘beforeValidate’]回调函数,同时针对各个属性加入 htmlOptions[‘beforeValidateAttribute’] 的回调,如果JS有错就返回 false阻止AJAX验证。

所有的JS验证规则直接从 model 的 validator 里取得并转换,所有能做的基本上做了转换,但由于CValidator的写法没有考虑这处情况,导致转换代码都偏长。

已支持的验证器包括:‘CRequiredValidator’,‘CRegularExpressionValidator’,

‘CEmailValidator’,‘CUrlValidator’,‘CCompareValidator’,

‘CStringValidator’,‘CRangeValidator’,‘CNumberValidator’,

‘CBooleanValidator’

  1. 当 js验证有错误时阻止表单提交,当某个字段的验证规则全部可以转换成JS验证时,如果JS验证都正确也禁止再向服务器提交AJAX验证(没必要)。

// 顺便 to Qiang, 看你也经常会来照顾中文版,呵呵

希望Yii team可以考虑把这项功能整合进官方的 ActiveForm,然后通过一个选项去控制它的开关。

具体参见该扩展主页:

http://www.yiiframework.com/extension/eactiveform/

抱歉,刚刚发布的版本在处理自动提交attributes时有个小BUG(当这个字段的所有验证器均无法转换成js验证时,如验证码),现已修正并作了直接更新(下载文件名没有改变),刚看到有2次下载,实在抱歉了。

这个很酷!你能提交一个google ticket么?我们会在未来的版本考虑把这些功能整合进去。谢谢分享你的工作!

非常好。

建议小改进:

  1. 可以在客户端给出message

  2. 以数组或者json格式给出message

你的意思是还要在这个基础上定制输出效果?其实目前是这样的,所有的 message 以及规则都是直接根据 CModel::getValidators($attribute) 直接取得的,和PHP端是完全同步的。

所以你这个建议我有点不是很明白。