最简单的使用
<script src="//qidian.gtimg.com/lulu/theme/modern/js/plugin/sea.js"></script> <script> seajs.config({ 'base': 'http://qidian.gtimg.com/lulu/theme/modern/js' }).use(['common/ui/Validate'], function(Validate) { new Validate($('#form'), callback, options); });
基于HTML5的表单验证
①. 基本说明
基于HTML5规范的表单验证交互组件。依赖ErrorTip组件。
- 内置type类型包括:
email
,tel
,url
,zipcode
,number
,date
,hour
,minute
,time
,date-range
. 在高版本IE浏览器的向下兼容模式下,会自动将一些type直接text化,这在原生浏览器下是没有问题的。真实用户场景不会存在此问题,如果大家实在拗不过测试同学,可以在type
类型后面加个空格,例如type='email '
. 这些类型输入框默认内置正则表达式。 - 自定义正则表达式,使用原生HTML5属性
pattern
. 例如:pattern="^\d{16}$"
. - 范围超出,如数值输入,range数值范围选择,以及日期和时间的起止限制,使用原生
min
,max
,step
属性。 - 内容长度限制,使用原生
maxlength
, 以及minlength
。本组件会自动选择超出部分的文字。 - 内置计数和计数验证功能,只要使用UI组件通用的HTML和类名结构(可参考文本框和文本域静态UI组件相关文档)。中英文计数规则使用
lang
属性控制。没有lang
属性,表示中英文1:1
;lang="en"
表示后面的数值是字符数,1个汉字等于2个英文字符,lang="zh"
表示后面的数值是汉字数,2个字母等于1个汉字。
验证规则
默认不验证,点击“提交”按钮后开启即时验证,所有有误内容标红,但是提示tips只会出现在第一个或当前active控件上。
如果不走表单,或者一开始就验证,后面均有使用示意。
② 测试兼演示
// 表单验证 var pwd = $('#pwd'), pwdAgain = $('#pwdAgain'); // 文件上传按钮元素 var btnFile = $('label[for="validateFile"]'); // 隐藏input框 var hiddenFile = $('#idImgUrl'); // 如果选择文件 $('#validateFile').change(function() { // 直接trigger hidden input框change事件 hiddenFile.val('xxx.png').trigger('change'); }); // 验证绑定 new Validate($('#validateForm'), function() { new Dialog().alert('全部验证通过'); }, { validate: [{ // 演示替换内置的提示 id: 'bankAccount', prompt: { unmatch: '银行账户只能是16位数值' // 否则提示文字就是内置的“内容格式不符合要求” } }, { id: 'pwd', // 演示添加自定义的验证 method: function(el) { var valueAgain = pwdAgain.val(); if (valueAgain && el.val() != valueAgain) { return '前后密码不一致'; } else { pwdAgain.removeClass('error'); } } }, { id: 'pwdAgain', method: function(el) { if (el.val() != pwd.val()) { return '前后密码不一致'; } else { pwd.removeClass('error'); } } }, { id: 'idImgUrl', // 验证头像必传 method: function(el) { // el指存放身份证图片地址的hidden类型的input框 // 隐藏元素无法定位,转移提示元素给按钮 如果目标静态,建议放在外面; 如果是动态的,则必须用在method方法中 el.data('target', btnFile); // 返回错误提示 if (el.val() == '') { return '尚未上传头像'; } } }] });
证件照验证相关HTML代码:
<label for="validateFile" class="ui_button">上传照片</label>
<input type="hidden" id="idImgUrl">
<!-- 在验证form之外的上传头像form -->
<!-- 上传文件的表单 -->
<form><input type="file" id="validateFile" class="clip" accept="image/*"></form>
注意,上面hidden
input没有添加required
属性,所以对应的是自定义的method方法。如果添加了required
属性,如下:
<input type="hidden" id="idImgUrl" required>
则自定义验证的参数不能使用method
方法,而需要使用prompt
. 例如:
{ // required设置时候的处理 id: 'idImgUrl', prompt: { ignore: '尚未上传头像' // 如果值是字符串,则需要在语句外面转移提示元素。如果是函数,可以写在里面。 } }
③ 语法和API
new Validate($('form'), callback, options);
你没有看错,1行代码就可以满足各种验证需求。另外,也可以使用包装器方法:
$(form).validate(callback, options);
其中,callback
是所有表单验证通过后的回调方法。
options
为可选参数,具体见下表:
参数名称 | 支持类型 | 默认值 | 释义 |
---|---|---|---|
validate | Array | [] |
内置验证以外的自定义提示和验证方法。为对象数组集。如[{}, {}] , 其中,每个对象格式对下:
id: '', // 元素的id, 必须 prompt: { // 用来替换内置的提示文字,支持Function类型, 可动态返回提示字符串内容 ignore: '', // 值为空时候的提示文字 unmatch: '', // 格式不匹配时的提示,参见上面例子银行账户提示 out: { // 值范围超出时的提示文字 min: '', max: '', step: '' }, overflow: { // 内容长度超出时候的提示文字 minlength: '', maxlength: '' } }, method: $.noop // 其他自定义的验证,例如本例的前后密码一致验证 其中上下文this指当前实例对象,支持一个参数, 为当前表单元素 // 返回错误提示内容字符串,其他返回值(包括undefined) 都认为是验证通过 |
multiple | Boolean | true |
提交时候是全部错误高亮,还是仅仅第一个 |
immediate | Boolean | true |
是否在表单提交后开启即时验证 |
labelNew | Boolean | false |
是否使用关联label元素中裸露的文字作为提示关键字,默认关闭 |
onSuccess | Function | $.noop |
当前表单元素验证通过时候执行的回调。 |
onError | Function | $.noop |
当前表单元素验证没有通过的时候执行的回调。 |
④ 一些重要说明
请使用原生
<form>
元素,内置submit
类型按钮,默认disabled
. 防止JS还没有初始化,用户点击按钮,触发原始的表单提交。另外,由于原生按钮在低版本IE下有黑色线框以及尺寸不好控制,可以使用
<label>
元素for
属性和按钮的id
属性进行关联。例如:<input type="submit" id="validateSubmit" disabled class="clip"> <label for="validateSubmit" class="ui_button ui_button_primary">提交</label>
支持自定义的文字提示和额外的自定义验证,就是使用
validate
可选参数就可以了,支持的基本参数可参见上面关于“option可选参数”的表格。需要进一步补充说明的是,自定义提示文字,支持Function类型参数,实现动态提示效果。例如
unmatch
只是单纯的类似“不匹配”的含糊提示。从用户角度讲,存在提示细分的需求,此时,可以使用Function类型值做进一步的提示内容细分处理。例如下面链接地址细分提示演示代码(取自实际项目):validate: [{ id: 'some_id', prompt: { unmatch: function(el) { var value = el.val(), arr = value.split('://'); if (arr.length <= 1 || (arr[0] != 'http' && arr[0] != 'https')) { return '必须以http(s)://开始'; } return '链接地址错误'; } } }]
正如所见,当使用Function类型参数时候,支持一个可选参数,和method参数一样,表示当前验证元素空间的jQuery包装器对象。上下文
this
指当前DOM元素。支持
hidden
类型的元素验证,但是,由于errroTip提示无法定位隐藏元素,因此,请使用类似下面的代码转移最终真正的提示元素:$('input[type="hidden"]').data('target', $(target));
⑤ 非表单元素的验证
从我个人理想主义的角度讲,我希望所有的验证和提交走原生的form
元素。
但是实际情况下,有时候提交按钮就是普通的元素标签,例如,Dialog弹框的确认按钮。此时无法触发弹框内的form
元素的submit
事件。
还有的时候,压根就没有使用form元素。
遇到上面两种情况,我们该如何是好?不要担心,Validate.js支持普通元素的验证处理。
参考下面的例子,一个input
框在普通的div
中有个普通的a
标签按钮。
<div id="notForm" class="p10 bgwh"> <span class="ui_input ui_search_input"> <input type="search" required> <a href="javascript:" class="ui_icon_search">搜索</a> </span> <a href="javascript:" class="ui_button ui_button_primary">搜索</a> </div>
JS代码如下:
// 非表单元素验证
var noForm = $('#notForm');
var noFormValidate = new Validate(noForm, null, {});
noForm.find('a').click(function() {
if (noFormValidate.isAllPass()) {
new Dialog().alert('无表单验证通过');
}
});
跟原生form
验证相同之处在于支持自定义的提示和自定义的验证方法,一次全局验证后,开启即时验证;不一样的地方在于,验证成功的方法(isAllPass
方法)需要自己调用,回调也是需要自己处理的。
关键就是:验证实例.isAllPass()
方法。
上面的JS代码解读就是:
给元素注册验证方法(会验证所有表单类型子元素),当点击按钮的时候,如果全部通过(同时悄悄开始了即时验证),则弹出弹框。
⑥ 扩展自定义的验证类型New
除了内置的email
, tel
等类型,Validate还支持自定义的类型,例如,下面扩展了短信验证码、座机移机身份证号码验证类型。
$.validate.reg = $.extend({}, $.validate.reg || {}, { code: '^\\d{6}$', phone: '^\\d+(?:\\-\\d+)*$', id: '^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|[Xx])$' }); $.validate.name = $.extend({}, $.validate.name || {}, { code: '短信验证码', phone: '座机', id: '身份证号码' });
使用的时候,指定type
值就可以,例如:
座机:<input type="phone">
⑦ 一开始就开启失焦验证
// 一开始就失焦验证 var blurForm = $('#blurForm'); var blurValidate = new Validate(blurForm, function() { new Dialog().alert('验证通过'); }); // 添加失焦验证事件处理 blurForm.find(':input').each(function() { $(this).blur(function() { if (!blurForm.data('immediate')) { // 如果没有开启即时验证 $.validate.focusable = 0; blurValidate.isPass($(this)); } }); });