Validator


版本

V1.0


简述

Validator组件为表单提供定制的验证功能,基本满足项目开发过程中的表单校验需求,使用简单、灵活。


快速入门

1. 原理

表单元素触发blur、change、click事件,获取当前表单元素value值,判断元素值是否符合该元素配置的所有校验规则,并处理校验结果。处理结果最终以正误状态的不同样式表示。

2. 导入js库

组件依赖于jQuery,在js中引入组件时,要先引入jQuery库(版本不低于v1.11)。

// 这里用url指代项目中组件存放的路径
<script src="url/jquery.js"></script>
<script src="url/validator.js"></script>

3. 简单示例

实现一个对输入框进行非空校验、错误提示信息为“输入不能为空!”的效果,如下:

HTML

<form class="form-group">
    <div class="field-group">
        <label class="field-label">输入框</label>
        <input type="text" value="" class="field-control" name="title" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
</form>

JS

var $form = $(".form-group");
var validator = new Validator( $form, {
    groupClass: 'field-group'
});

上述示例的DOM结构,是组件默认的标准结构: 1)每个校验组要包含一个表单元素和一个显示错误信息的div,<div class="field-msg"></div>为提示信息显示的容器,若无此div,则信息不显示,class="field-msg"为默认值; 2)校验组的最外层,需要有一个包裹的容器,容器的默认class名为“field-group”。组件通过外层容器的class来获取每个校验组。

4. 正则校验

对于input和textarea,多数情况有通过正则校验来限制输入内容的需求,可通过组件提供的pattern、invalid属性实现。例如要求输入内容限制在1~30个字符内,实现如下:

<form class="form-group">
    <div class="field-group">
        <label class="field-label">输入框</label>
        <input type="text" value="" class="field-control" name="title" 
               pattern="^[\s\S]{1,30}$" invalid="输入框最多填写30个字符!"
/>

        <div class="field-msg"></div>
    </div>
</form>

pattern属性是正则校验规则,invalid为不满足此校验规则时的错误提示信息。

5. 整体校验

组件触发校验的条件是blur、change、click,由于用户操作的不可控性,存在未触发校验的可能。通常,在提交表单或其他操作前,需要对所有表单输入的合法性进行校验。组件提供的validateAll方法能对表单进行整体校验,若所有表单验证通过,函数返回true,否则返回false,并将有误校验组置错误状态。例如,当所有表单校验通过,可提交,实现如下:

if (validator.validateAll()) {
    submit();
}

以上内容,基本可以满足大部分简单的表单开发需求。下文将详细介绍Validator组件及组件更多的使用方法。


入口参数

组件入口提供两个参数,如下:

Validator(container, options)

参数 必选 类型 描述
container true jQueryObject 获取整个需要校验的表单对象或目标元素对象,用于限制上下文
options false Object 可选项配置参数

在使用组件时,需要在JS文件中实例化组件。


options

可选项options包括组件默认的错误提示样式和事件触发方式。

参数 类型 必要 描述 默认值
groupClass String false 每个校验组最外层容器的标识CSS类,若重定义此类名,DOM结构最外层容器class名需保持同名;若不设置此属性值,DOM结构最外层容器class名需严格按照默认值 field-group
errorClass String false 表单元素错误样式的CSS类名,若使用自定义的CSS样式,可修改此类名 field-error
msgClass String false 提示信息样式的CSS类名,若使用自定义的CSS样式,可修改此类名 field-msg
infoClass String false 设置表单元素额外的错误样式CSS类名(通常不使用) --
passClass String false 设置校验通过的样式名(通常不使用) --
normalValidEvent String false 普通控件触发事件 blur.validator/change.validator/validator-force(自定义的强制校验事件)
instantValidEvent String false 输入时立即触发事件【TODO】(组件未绑定该事件) input.validator/propertychange.validator
tipEvent String false 点击事件 click.validator

参照上表,在实例化组件时,通过可选项可配置个性化组件。通常,默认的触发事件、点击事件等重定义相对少,多数是样式修改。组件中有validator.less文件用于控制默认的错误状态样式,如下所示(例中使用less语法描述):

.form-group-error,
.field-group-error {
    .field-msg { /*错误信息显示样式*/
        color: #F96E6E;
        font-size: 12px;
    }
}
.field-msg { /*info信息显示样式*/
    display: inline-block;
    color: #919599;
}
.field-error { /*校验错误表单元素高亮提示样式*/
    border-color: #F96E6E;
}

若需定义样式,全局修改可以使用样式覆盖的方法,但如果只是局部修改,组件提供更好的方法。配置options对应的样式控制参数,再在自定义的样式文件中编辑。

1. groupClass

groupClass对应的值为每个校验组最外层容器的class名,若不使用表单组的最外层容器默认的class名,例如将class名写为“my-group”,实现如下:

var validator = new Validator( $form, {
        groupClass: 'my-group'
    } );

HTML最外层的容器class名需要和groupClass值一致:

<form class="form-group">
    <div class="my-group">
        <label class="field-label">输入框</label>
        <input type="text" value="" class="field-control" name="title" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
</form>

同时,组件会在错误状态的校验组最外层容器的class中,加上容器class名-error的CSS类来标识,如“my-group”在错误状态下会增加一个“my-group-error”。如下为示例误状态的DOM:

<form class="form-group">
    <div class="my-group my-group-error">
        <label class="field-label">输入框</label>
        <input type="text" value="" class="field-control field-error" name="title" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
</form>

注意对照validator.less,可以发现,修改groupClass值后,错误提示信息的样式会使用正常提示信息样式,无显著差异。 若需要区别两种提示信息,还需在CSS文件中重新编辑错误提示信息的样式。如下(less语法表述):

.my-group-error {
    .field-msg { /*错误信息显示样式*/
        color: #F96E6E;
        font-size: 12px;
    }
}

2. errorClass

errorClass用来重定义表单元素的错误样式类名。例如,实现一个错误信息显样式为边框yellow高亮的效果:

假设js中errorClass的类名为“my-error”

var _validator = new Validator( $form, {
        errorClass: 'my-error'
    } );

CSS文件编写如下:

.my-error {
    border: 1px solid yellow;
}

校验规则配置

组件通过配置表单元素的Attribute属性,可进行个性化的控件的校验规则设置。

属性 必要 说明 适用元素
required false 进行非空校验 input/textarea/select
empty false 输入为空时的提示信息,前提是配置required input/textarea/select
pattern false 自定义一个正则表达式校验规则 input/textarea
invalid false 输入不满足自定义校验规则的提示信息,前提是配置pattern input/textarea
custom false 设置自定义事件,custom值为事件名,绑定事件后,校验时会触发同名事件 input/textarea/select
cmsg false 自定义事件返回状态为reject时的提示信息,前提是配置custom input/textarea/select
info false 表单在聚焦时且无错误提示时显示的提示信息 input/textarea/select
novalidate false 默认的校验表单元素有input、textarea和select,当在这些元素中增加novalidate属性时,当前的元素就不再做校验。 input/textarea/select/checkbox
validate false 除默认表单元素(input、textarea和select)外,还可对特殊元素进行校验,这时,加上validate属性,就会对该元素进行校验。 其他非默认表单元素

除快速入门一节列举的最常用的四个属性外,这里再介绍几个实用的属性。

1. novalidate

含novalidate属性的form、input、select和textarea元素不会被校验。如下:

<form class="form-group" novalidate>
    <div class="field-group">
        <label class="field-label">不校验的input</label>
        <input type="text" value="" class="field-control" name="title" 
               empty="输入不能为空!" required />

        <div class="field-msg"></div>
    </div>
</form>

2. info

input、textarea、select聚焦时,显示info中的提示信息,失焦时隐藏。如下:

<form class="form-group">
    <div class="field-group">
        <label class="field-label">普通提示信息</label>
        <input type="text" value="" class="field-control" name="title" info="这里是提示信息"/>

        <div class="field-msg"></div>
    </div>
</form>

3. custom

custom可用来配置自定义事件,如自定义一个名为“e-test-event”事件,检验过程会触发一个同名事件。该事件的逻辑处理过程被定义为一个Deferred对象,当返回状态为reject时,会显示cmsg中的内容。如下:

<form class="form-group">
   <div class="field-group">
        <label class="field-label">确认密码</label>
        <input type="text" value="" name="pwd_new_confirm" 
               empty="确认密码不能为空!" required 
               custom="e-test-event" cmsg="两次密码输入不一致"/>

        <div class="field-msg"></div>
      </div>
</div>

JS中需将自定义事件绑定到组件的eventCenter,如下:

validator.eventCenter.on('e-test-event', function(e, data) {
    //组件会传入data数据[{'def': def, 'target': target}],
    //其中def为一个Deferred(),当返回reject状态时,显示cmsg中的信息;

    if (...) {
        def.reject();
    } else {
        def.resolve();
    }
});

API

组件提供的一些内置属性和方法便于使用。

属性名 返回类型 描述
eventCenter Validator 用于绑定自定义事件
$form jQueryObject 获取整个校验对象
$fields jQueryObject 获取每个表单中每个校验对象
函数名 返回类型 描述
validateUntilError(collection) Boolean 用于校验表单中是否有不满足验证规则的元素,参数collection为可选,默认为组件入口传入的表单对象,当设置参数时,要求参数为需校验的表单元素的父级元素的jQuery对象
validateAll(collection) Boolean 用于校验所有表单元素中是否满足验证规则,参数collection为可选,默认为组件入口传入的表单对象,当设置参数时,要求参数为需校验的表单元素的父级元素的jQuery对象
reset(target) undefined 将校验的所有状态置为初始状态。参数target为可选,默认为所有校验的表单元素对象,当设置参数时,参数为目标元素的jQuery对象

1. eventCenter

eventCenter为组件的事件处理中心,实现方法是返回了一个当前的validator对象。可以将组件在校验过程中触发的事件绑定在该属性上。如上一节custom所示,自定义事件被绑定在eventCenter。在异常处理时,通常也会将异常处理事件绑定在eventCenter中。

2. validateAll(collection)

validateAll可校验所有表单元素都是否满足验证规则,参数为可选。通常,DOM结构为组件默认的标准结构时,validateAll不传入参数,默认会获取整个表单进行整体的校验。对于特殊情况,validateAll需要传入参数。

2.1. 校验指定元素

校验指定元素,函数传入参数为指定元素的父级元素的jQuery对象。例如,只校验表单中含有need-check类的元素:

<form class="form-group">
    <div class="field-group">
        <label class="field-label">不校验</label>
        <input type="text" value="" class="field-control" name="" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
    <div class="field-group need-check">
        <label class="field-label">校验</label>
        <input type="text" value="" class="field-control" name="" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
</form>
<button>校验指定元素</button>
var $form = $("form");
var $targetParent = $(".need-check");
var $btn = $("button");

var validator = new Validator( $form, {
        groupClass: 'field-group'
    } );

$btn.click(function () {
    validator.validateAll($targetParent);
})

2.2. 校验任何结构中的表单元素

很多情况下,控件的DOM结构是不定的,往往表单元素并不一定包含在form中。如下,一个表格中存在需要校验的表单元素:

<tbody>
    <tr data-bidding-id="<%$value.bidding_id%>">
        <td>
            <input type="text" class="form-control input-sm" required pattern="^\d+\.?\d*$" value="">
            <a href="" class="submit">提交</a>
        </td>                    
    </tr>
</tbody>

相应的js中,实例化时传入含有目标元素的外层容器,调用校验方法时传入目标元素的父级元素的jQuery对象即可,如下:

var $tbody = $("tbody");
validator = new Validator($tbody); 

$tbody.on('click', '.submit', function (e) {
   e.preventDefault();
   var $this = $(this);
   var $tr = $this.closest('tr');

   if (validator.validateAll($tr)) {
       submit();
   }
});

3. reset(target)

组件默认会在验证表单合法后重置校验组的状态,即恢复到无错误显示的样式。如果想手动将错误状态的校验组恢复为最初状态,可使用reset()函数。函数不传入参数,则默认将整个表单中所有校验组恢复初态。若只恢复某个目标元素,例如只恢复“target-demo”标识的校验组,则:

<form class="form-group">
    <div class="field-group target-demo">
        <label class="field-label">输入框</label>
        <input type="text" value="" class="field-control" name="title" 
               empty="输入不能为空!" required/>

        <div class="field-msg"></div>
    </div>
</form>
<button>重置</button>
var $button = $("button");
var $target = $(".target-demo");

$button.on('click', function () {
    validator.reset($target)
});

异常处理

组件内部提供了异常处理的方法,throwException为内部抛出异常的方法,错误信息数据以事件形式抛出,事件名为“validator-error”。

错误信息数据data的结构如下:

字段 类型 描述
target Object 当前的目标元素对象
log Object 记录相关的日志信息
log对象中的几个字段:
mod: 记录'log-mod'的属性值;
position:返回当前元素的name或id值;
type:报错产生行为;
sort:当前校验规则的index;
value:当前表单元素的value值

对于异常处理,可以将抛出事件绑定在组件的eventCenter中来对异常信息进行处理:

validator.eventCenter.on('validator-error', function(e, data) {
    Log.send(data.log);
});