jQuery html5Validate基于HTML5表单验证插件

这篇文章发布于 2012年12月20日,星期四,13:43,归类于 jQuery相关。 阅读 367807 次, 今日 21 次 111 条评论

 

更新于2018-05-08

经过不断锤炼,LuLu UI已经正式开源啦:https://github.com/yued-fe/lulu

其中表单验证文档参见:https://l-ui.com/content/apis/validate.html

可以模块化调用,也可以作为插件直接直连使用,文档底部有单独使用的demo演示

多年数个千万PV项目检验与打磨,体验和细节都非常值得称道。

下面这些以前写的更新提示可以忽略啦~

更新于2016-07-08
又有不少人问了,开源还需要时日。不过大家现在是可以使用的,下面是最简单使用,需要seajs:

<script src="http://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);
});

然后,我也把文档给独立出来了,您可以狠狠地点击这里:海量用户产品验证过的表单验证组件demo兼文档

别看写得很多,其实基本使用很简单的。后面的文档只要是面向复杂定制的。

如果上面的使用还是觉得不够简单,可以试试直接使用下面的JS地址:

<script src="http://qidian.gtimg.com/c/=/lulu/theme/modern/js/common/ui/Validate.js,/lulu/theme/modern/js/common/ui/ErrorTip.js,/lulu/theme/modern/js/common/ui/Follow.js"></script>

可以直接使用包装器方法,例如:

$(form).validate(callback, options);

更新于2016-02-25
前面提到的新版目前线上已经可以访问:
http://mp.gtimg.cn/old_mp/assets/js/common/ui/Validate.js

demo体验狠狠地点击这里

解决了之前组件如下不足:
1. 自定义验证顺序有问题;
2. 即时验证支持没内置;
3. 不能随意定制验证规则;

等等。

今年会开源,大家稍安~

更新于2014年12月18日 0:35
本插件已经迁移至Github上更新与维护:https://github.com/zhangxinxu/html5Validate

一、前言

前3篇文章实际都是为本文做铺垫的,如果以下棋表示,前三篇是普通走棋,本篇是将军!

目前市面上有不少表单验证插件,看似强大,实在糟糕!

总结下,有以下一些问题:

  1. 过多干预
    包括:改变了表单元素UI, 为表单元素绑定过多事件等
    表单验证与过多干预 张鑫旭-鑫空间-鑫生活
  2. 布局等限制
    包括:需要特定结构的布局,需要特定的类名或者ID
    表单验证与布局限制 张鑫旭-鑫空间-鑫生活
  3. 学习成本
    包括:N多元作者自定义的属性,或者自定义的特定的数据结构
    表单验证与学习成本 张鑫旭-鑫空间-鑫生活
  4. 可用性
  5. 当JS出现错误的时候而无法正常运作的时候,验证就是聋子的耳朵——摆设,即使在现代浏览器下也是如此。

面向未来的表单验证

  1. 验证驱动
    验证信息HTML驱动,例如HTML5中required, pattern, multiple
  2. 验证形式
    非即时响应,submit验证,如Chrome浏览器的处理;或者弱即时响应,如FireFox浏览器仅仅红色外发光。
  3. 验证交互
    浮动形式,尖角指示。
    现代浏览器的验证出错提示 张鑫旭-鑫空间-鑫生活

换言之,所谓面向未来的表单验证,是遵循W3C HTML5规范的表单验证,我们可以从目前领先的浏览器中看到大致雏形。而本文所有展示的html5Validate表单验证插件,就是基于这个未来设计的。

二、html5Validate概述

html5Validate插件的验证机制、交互形式甚至形式与Chrome浏览器HTML5表单内置验证走的很近。在使用的时候,就是写写原生的HTML5表单代码。我只想说:走阳光大道和过独木桥的感觉是完全不一样的。

举个简单例子,一个邮箱验证,HTML5代码表示应该是下面这个样子:

<input type="email" required>

好巧的是,使用html5Validate进行表单验证的时候,也是使用上面这段HTML代码!

类似下面的绑定:

$("form").html5Validate();

于是,您在提交表单的时候会(在各个浏览器下)看到这样子的提示:
请填写字段的提示 请输入电子邮件的提示

跟Chrome浏览器下的提示文字近似:
Chrome浏览器无字段提示 张鑫旭-鑫空间-鑫生活 Chrome浏览器下邮件地址有误提示 张鑫旭-鑫空间-鑫生活

html5Validate支持我所知的HTML5验证相关的东西,如type="email", type="number", type="tel", type="url", step, min, max, required, pattern, multiple等,并有一些本地化扩展,如增加了type="zipcode"邮编等,支持type="hidden"的完整验证(HTML5中是忽略的),支持多type共存,例如type="email|tel", 可以让文本框输入邮箱或者手机号码。

type="date", type="hour", type="password"等因为不同网站规则不一样,因此,没有放在html5Validate中,不过,您可以很简单地进行扩展,使您的项目支持之,这个后面会介绍(参见 part 9-4)。

为了满足实际开发需求,额外增加了四个自定义属性值:data-key, data-target, data-min, data-max. 具体何用,下面会详细讲解。

支持自动的全角转半角。

注意type="submit", type="reset", type="file", type="image"以及disabled的表单元素没有验证性可言,因此,下面所说的表单元素,并不包括他们。

兼容性
html5Validate通过jQuery1.4+测试,支持正常IE6-IE10浏览器,FireFox, Chrome等现代浏览器。

三、demo、使用以及资源下载

以下灰色文字内容可忽略,已过时~

您可以狠狠地点击这里:html5Validate表单验证jQuery插件测试demo

下载
未压缩版JS:jquery-html5Validate.js
压缩版JS:jquery-html5Validate-min.js

zip源文件打包下载(含测试demo)(右键-[目标|源文件]另存为):jquery-html5Validate.zip

更新于2014年12月18日 0:35
本插件作为jQuery插件迁移计划先头兵,已经迁移至Github上更新与维护:https://github.com/zhangxinxu/html5Validate

资源下载、或者使用遇到什么问题,可以去Github上提问,我会及时更新与建设,也欢迎大家一起参与。

使用

  1. 引用jQuery框架,示意:
    <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
  2. 引用html5Validate插件,示意:
    <script src="http://www.zhangxinxu.com/study/js/mini/jquery-html5Validate-min.js"></script>
  3. 绑定调用:
    $().html5Validate(callback, options);

    示意,假设测试表单idhtml5Form,则有:

    $("#html5Form").html5Validate(function() {
        // 全部验证通过,该干嘛干嘛~~
    });

//zxx: 还有一些实际应用的例子将会在本文后半部分展示。

四、可选参数以及详解

可选参数见下表:

参数名称 默认值 简单释义
novalidate true 布尔型。是否取消现代浏览器的内置验证
submitEnabled true 布尔型。表单中禁用的提交按钮是否使之可用
labelDrive true 布尔型。是否优先使用label标签中的文字作为提示关键词
validate function() { return true; } 包含返回值的函数,插件自带验证以外的其他验证

1. 参数novalidate
既然html5Validate插件验证与原生HTML5验证公用一套HTML代码,显然就存在共存的问题。

如果没有设计这个参数novalidate或者novalidate值为false, 则浏览器内置表单验证优先,全部pass之后才轮到插件进行验证,也就是说,两者是没有冲突的。其实,原本我是不打算设计这个参数的,因为,我觉得浏览器内置的验证以及交互效果很赞的,但是,IE10的出现让我速速打消了这个念头,因为,丫丑得我根本无法直视——大红的粗框框!!
令人啧舌的IE10 验证提示UI 张鑫旭-鑫空间-鑫生活

novalidate为HTML5表单内置的属性(W3C草案),可以让现代浏览器(IE10+, FireFox, Chrome, Opera等)默认不对表单做验证(忽略required, pattern等)。html5Validate插件默认novalidate: true也就是说,其默认对包装器元素添加了novalidate="novalidate",以阻止浏览器的默认验证,下图代码为JS生成之后所截:
novalidate的添加截图示意 张鑫旭-鑫空间-鑫生活

这就是为什么测试demo在FireFox等浏览器下不出现内置提示效果的原因。

可能您有这样的需求,您希望除了IE10以外的现代浏览器都使用浏览器自带的验证规则以及提示效果,怎么办,可以像下面这样?

var isIe10 = typeof document.msHidden !== "undefiend";
$("form").html5Validate($.noop, {
    novalidate: isIe10? false: true
});

2. 参数submitEnabled
这个参数的设计是很有必要的。

很多时候,我们的表单是Ajax提交的,当页面加载不是很及时的时候——如表单元素呈现,但验证脚本未绑定——,用户回车一个输入框,悲剧来了,默认表单的submit被触发了,而不是ajax提交……

我不清楚其他团队是怎么处理的,我处理这类问题是表单元素的提交按钮默认disabled,在表单验证脚本绑定OK之后,去除disabled属性,使一切正常。

submitEnabled参数的作用就是让表单中的禁用的submit性质的按钮可用。

例如,测试demo中,默认按钮是disabled的,这样,就算JS因网络等原因被block了,用户也无法提交表单,避免造成更加不好的体验。
表单提交按钮默认disabled 张鑫旭-鑫空间-鑫生活

等验证事件初始化完毕,自然,disabled的按钮被enabled了。

对于原生submit()的表单或者可以submit()的表单,此参数酱油,您可以无需disabled提交按钮。

3. 参数labelDrive
顾名思意,label驱动。该参数针对错误提示框中的文字内容。

这是与浏览器内置提示文字不一样的地方,优先label标签文字提示。什么意思?

html5Validate插件有两套文字提示机制。一种是label标签驱动,其次是内置固定提示文字,如“请填写此字段”。

//zxx: 对于单复选框以及按钮,由于点击它们对应label标签会触发选中或者按钮事件,因此,对于这些元素,labelDrive参数是完全的酱油 – 提示文字与label毫无关系。对于下拉框而言,其在隐藏状态下,提示文字可以从label获取;非隐藏状态也是酱油。

何为label标签驱动?举个例子:

<label for="email">邮箱:</label><input type="email" id="email" required>

上面HTML的提示文字就是:
label标签驱动之邮箱提示 张鑫旭-鑫空间-鑫生活

如果对应label标签中的文字是“邮箱/手机”,则提示文字是:
label标签驱动之邮箱/手机提示 张鑫旭-鑫空间-鑫生活

也就是说“label标签驱动”就是把label标签中的文字作为提示关键字,这样子的提示更智能,同时也不会增加额外的HTML代码。

该文字如何获取
①找到与表单元素id对应的label元素(for关联),如果没有则应用内置提示文字规则;
②获取label标签中的文字,过滤星号(*),中文冒号(:)和英文冒号(:),剩下的文字作为提示关键字出现在提示框中,如果输入框内容为空则提示“您尚未输入***”;格式不准确则提示“您输入的***格式不准确”。
③如果label标签文字与表单元素的placeholder值一样,则此label标签酱油。
④如果有多个label元素,符合要求的提示文字会累加。
⑤如果最后得到的label标签文字为空,同样应用泛泛的提示文字(如“请填写此字段”或“内容格式不符合要求”)。

小技巧
你可以隐藏label标签(如demo中两个拖选);或部分隐藏,如demo中评论部分:

<label for="comment">评论内容:</label><textarea id="comment" rows="5" required data-min="5" data-max="100">

提示文字为“您尚未输入评论内容”,而不是“您尚未输入评论”。

4. 参数validate 新增于2013-06-19
新增参数validate. 实际开发的时候,各类验证需求层出不穷。例如,今天@jason就在评论中提到,是否可以指定多选就3项。这不属于HTML5规范中验证,也不是常规验证需求,在插件中添加此方法是有违插件的设计原则的,因此,插件内部是不会支持这类验证的。

在我的实际项目中,MooTools版的html5Validate插件是有一个可选参数validate,参数值为函数,就是一个额外验证的函数,专门对付一些特殊的验证需求。今天正好也为jQuery版增加下这个参数。

插件内部是如此运作的,先执行插件内置的验证,然后,再执行validate这个验证函数,如果返回值是true,则执行我们相对表单进行的回调操作。

言语苍白,demo明了。您可以狠狠地点击这里:html5Validate新增validate参数demo

demo中有两个额外的验证:一是前后密码需要一致;二是多选项至少选择3个。大致截图如下:
测试需求

然后,相关JS如下:

$("form").html5Validate(function() {
        alert("验证全部通过!");
        this.submit();
    }, {
    validate: function() {
        // 下面这些就是额外的一些特殊验证
        if ($("#pwdCheck").val() !== $("#pwd").val()) {
            $("#pwdCheck").testRemind("前后密码不一致");
            return false;  
        } else if ($("input[type='checkbox']:checked").length < 3) {
            $("#checkBox").testRemind("至少选择3项");
            return false;  
        }
       return true;  
    }
});

注意需要有Boolean类型返回值,验证出错返回false验证就会停止,效果达到。

至少选择3项的提示

五、四个自定义属性

HTML5的表单验证html5Validate自然支持,但是,仅仅HTML5的东西貌似不能完全支持实际的各类需求,因此,html5Validate中还有4个自定义属性(就是前面提到的data-key, data-target, data-mindata-max),帮助覆盖95%+的验证需求。

1. 自定义属性”data-key”和”data-target”
这两个参数是为模拟表单(或称为“自定义表单”)设计的。

何为模拟表单?如自定义的下拉框,或者星星评分选择等……
模拟表单星星评分示意 张鑫旭-鑫空间-鑫生活

① “data-key”作用
模拟表单往往都是纯鼠标操作的,此时,类似“请填写此字段”或者“您输入的……”就显得不准确,不准确的关键就是这里的操作动词“填写”与“输入”。"data-key"的值就表示这个关键动词,如demo中的第二个拖选:

<label for="serverScore" class="dn">服务评分</label>
<input type="hidden" id="serverScore" required data-key="拖选" />

于是,提示的时候,就是:
拖选提示截图

注意:隐藏性质表单的"data-key"是可以缺省的,对于一般的隐藏输入框,默认"data-key"值为“输入”;对于隐藏的单复选框或下拉框,默认"data-key"值为“选择”。

① “data-target”作用
从可用性上讲,模拟表单都有一个对应的隐藏不可见的真实表单元素,或visibility:hiddenselect下拉框,或hidden类型的input框,或者display:noneradio们。

要知道,这些隐藏表单的位置是捕获不到(display:none;)或者位置不准确的。因此,浮动提示框的位置无法确定;就算浮动框位置确定了,指向了一个看不见的东西,用户也会很奇怪的。面对这种情况,"data-target"应运而生。

"data-target"可将黄色提示框的目标元素从真实表单元素转移到模拟表单元素(其值正是模拟表单元素的id(或className))。如果"data-target"不存在,或其值对应不到元素,则alert弹出提示,如上面这个截图。

如果"data-target"对应元素存在,则就会像下面这样提示(demo中第一个拖选)- 乾坤大挪移:
data-target效果示意截图

HTML代码如下:

<span id="hiddenRemind" class="bar_bg"><i class="bar_btn" data-rel="envirScore"></i></span>
<label for="envirScore" class="dn">环境评分</label>
<input type="range" id="envirScore" class="dn" required data-key="拖选" data-target="hiddenRemind" />

2. 自定义属性”data-max”和”data-min”
这两个自定义属性要好理解多了,一般用在文本域上或昵称文本框上,用做最多字符个数和最小字符个数限制。例如demo最后文本域:

<textarea id="comment" rows="5" data-max="100" data-min="5" required></textarea>

表示,评论内容需要5-100个字符。无论字符不足或者是超出,都会出现提示,其中,当内容超出的时候,html5Validate会自动帮你选中溢出部分的文字,例如下面截图:
文字溢出的部分选中提示 张鑫旭-鑫空间-鑫生活

六、一些验证类型的说明

1. type=number, 整数与小数
type=number文本框(数值文本框)的验证相对复杂点,这里有必要说下。数值文本框有step, min, max原生属性。min, max表示数值最小值和最大值,step缺省表示输入值必须整数,step0.1表示输入值最多1位小数(.00结尾除外)。

具体验证规则参见之前下的一步棋:HTML5 number类型文本框step属性的验证机制

数值文本框的UI
Chrome, Opera等浏览器下,数值文本框会有上下数值增减箭头;很多固执的设计师是无法容忍这个的: “the ui is so terrible!”
数值文本框的上下箭头

因此,实际上,不少团队的数值类型框还是老旧的type="text"以避免浏览器自带的上下箭头。OK,冲突来了,html5Validate需要HTML5代码做验证,实际实现不能使用HTML5的东西,怎么办?

很简单,在类型后面加个空格,例如,不是设置type="number",而是设置type="number "或者type="number|". //zxx: 管道符用来支持多type公用

html5Validate会自动过滤最后的空格,因此,相关的验证没有任何影响。

数值文本框与multiple
数值文本框不支持multiple, 此规则与浏览器一致。email/tel等类型支持multiple,多个邮箱或手机号使用逗号(,)分隔。

2. 不得不提的type=range
type=rangetype=number是近亲,均有step, min, max原生属性。然而,目前以及今后很长的一段时间,在web项目上,就验证而言type=range几乎没有用武之地,原因是UI限制。何解?

如果浏览器支持type=range,则用户完全是拖选操作(不能输入),几乎不存在范围溢出的情况,验证也几乎就是摆设;如果浏览器不支持type=range,其UI就是个普通输入框,其内部验证机制与type=number无异,如果撇开语义化以及可访问性不谈,是不是可以直接使用type=number

因此,个人看来,type=range只能作为隐藏的表单元素——为自定义表单元素服务,如demo中第一个拖选。也正因为这个原因,html5Validate并未重视type=range.

3. type=radio以及 type=checkbox的验证规则
无论是单选框还是复选框,只有是否必选的验证(required).

对于同一组单选框(name值一致),只要有一个单选框设置required就可以了(为了性能,也建议这么做)。单选框的提示文字固定,取自Chrome浏览器,为“请选择一个选项”。

对于复选框,哪个必选,就哪个需要设置required。其提示文字也是固定的,也是参考的Chrome浏览器,为“如果要继续,请选中此框”。不过,个人举得,复选框必选设置使非常让人蛋疼菊紧的。

七、内置插件testRemind介绍

jquery-html5Validate.js中还内置另外一个插件 – testRemind. 就是出现那个黄色提示框框的插件。

用法如下:

$().testRemind(content, options);

其中,content为提示的内容,可以包含HTML字符串;options为可选参数。

可选参数
参见下表:

参数名称 默认值 简单释义
size 6 数值。提示框尖角的尺寸大小
align “center” 特定字符串。提示框三角的位置,其他可选值为”left”和”right”
css
{
    maxWidth: 280,
    backgroundColor: "#FFFFE0",
    borderColor: "#F7CE39",
    color: "#333",
    fontSize: "12px",
    padding: "5px 10px",
    zIndex: 202
}
样式对象。提示框框的可变样式。

参数含义
① 参数size
没什么好说的,提示框框三角的大小。

② 参数align
没多少好说的,三角在框框的左边、中间还是右边。

在html5Validate中,一般的表单元素尖角都是在中间的,但是,单选框和复选框尖角实在左侧,如下图所示,这个设置目前暂不可变:
尖角位置居左的示意 张鑫旭-鑫空间-鑫生活

③ 参数css
该选项可以让你修改提示框的UI。

例如,通过如下的设置,我们可以让提示框框的效果长得跟Chrome浏览器近似:

$("input").testRemind("无论输入什么,都不合格!", {
    size: 10,
    css: {
        padding: "8px 10px",
        borderColor: "#aaa",
        borderRadius: 8,
        boxShadow: "2px 2px 4px rgba(0,0,0,.2)",
        background: "#fff url(chrome-remind.png) no-repeat 10px 12px",
        backgroundColor: "#fff",
        fontSize: 16,
        textIndent: 20
    }
}).get(0).focus();

于是,有类似下面效果(截自FireFox 17):
改造类似Chrome浏览器提示效果的框框 张鑫旭-鑫空间-鑫生活

您可以狠狠地点击这里:testRemind Chrome UI测试demo

几乎酱油的可选参数
在实际使用的时候,testRemind方法的这几个可选参数几乎是酱油的,因为html5Validate方法并未暴露相关参数可以修改弹出框框的UI,这是我故意这样设计的。

一来自己不希望html5Validate与testRemind方法有过多的耦合,因为这会让我觉得复杂,而产生不安;其次,对于一个项目而言,提示框框效果应该是整站统一,样式设置的限制未尝不是一件好事。

不过,此处小标题是“几乎酱油”,言外之意就是您还是可以通过一定的外部设置,改变提示框框的样式的。本插件JS中暴露了一个名为$.testRemind.css的对象,您可以对其加加减减来控制提示框的UI.

举个板栗,如下代码:

$.testRemind.css = {
    borderColor: "#a0b3d6",
    backgroundColor: "#f0f3f9"	
};
$("#testForm").html5Validate();

则,提示框框就会变成下面这幅屌模样:
改变边框色和背景色后的提示框框模样 张鑫旭-鑫空间-鑫生活

总结为:testRemind方法的CSS有限可选参数options中的css对象,如果没有,使用$.testRemind中的css对象。

注意:提示框出现后,点击提示框以外的页面任意位置,或在表单元素foxus状态下触发键盘,或改变浏览器的尺寸,提示框都会因此隐藏。

$.testRemind.display
除了$.testRemind.css外,还有一个$.testRemind.display属性,Boolean值(true/false),用来反映当前是否有弹框显示。关键时候,这个还是很管用的。

//zxx: 下面为广告~~注意不要勿点~~嘻嘻~~

八、高阶使用

$().html5Validate()方法是针对表单元素的,已经自动绑定了submit事件,并阻止了默认表单提交。然而,各类交互需求千变万化,自以为是的自动绑定可能满足不了苛刻的丈母娘,此时我们需要另外的处理,这就是这里要说的html5Validate的高阶使用。

html5Validate中有个名为$.html5Validate的对象,其中有一些方法,如验证元素是否为空($.html5Validate.isEmpty(ele)),是否合法($.html5Validate.isRegex(ele, regex, params))等,因为我比较懒,这几个方法不介绍。这里着重要提的是下面这个方法:

$.html5Validate.isAllpass(elements, options);

顾名思意:HTML5验证 – 是否全部通过!

1. 参数elements
elements参数必需,可以是:form节点,或者jQuery包装form,或者是需要验证的元素们。代码示意如下:

$.html5Validate.isAllpass(document.getElementsByTagName("form")[0]);
$.html5Validate.isAllpass($("form"));
$.html5Validate.isAllpass($("input, textarea, select"));

2. 可选参数options
options可选参数目前就一个,就是labelDrive,html5Validate方法中的参数labelDrive实际上是喂给$.html5Validate.isAllpass使用的。

$.html5Validate.isAllpass方法与表单没有任何关系,因此,我们可以更加灵活地应用在其他一些特殊场景上,举个简单例子,通过按钮点击事件验证并触发相关操作:

订阅优惠信息
<input type="email " class="email" placeholder="输入邮箱,如a@b.com" required />
<a href="javascript:" class="button">订阅</a>

然后,类似下面的验证处理:

$(".button").bind("click", function() {
    var email = $(".email");
    if ($.html5Validate.isAllpass(email)) {
       // 邮箱验证通过,该干嘛干嘛~~
    }
});

您可以狠狠地点击这里:$.html5Validate.isAllpass简单应用demo

isAllpass方法测试demo截图

九、其他可用的全局方法、对象及扩展

1. 全半角转换DBC2SBC方法
方法名称就是DBC2SBC,一个字符串参数,返回新的半角字符串,例如:

DBC2SBC("13208033621"); // 结果是"13208033621"

2. 检测元素是否可见
包装器方法,名称为$().isVisible(), 返回Boolean值,true/false.

这里的不可见指的是不能被focus的隐藏,包括type="hidden"隐藏域, display:none以及visibility:hidden, 屏幕外隐藏以及透明度为0等不在其中。

3. Boolean型属性检测
包装器方法,名称为$().hasProp(prop), 返回Boolean值,true/false.

所谓Boolean型属性指的是HTML5中required, multiple, novalidate等属性有,值缺省的属性。具体可参见“HTML5 Boolean属性值的JS获取”一文。

4. 全局对象OBJREG及扩展
全局对象OBJREG值完整截图示意 张鑫旭-鑫空间-鑫生活

此对象就是根据表单type类型进行对应验证的数据源所在,我们可以在JS源代码或者在外部对其进行扩展。举个例子,假设你们站点的日期只能是xxxx-xx-xx这种形式,则,你可以增加如下正则(此正则示意,实际验证并不完全):

OBJREG.DATE = "^[1|2]\\d{3}\\-[0|1]?\\d\\-[0-3]?\\d$"

于是乎,当提交表单含type="date"的输入框的时候,如果里面的值不符合上面的OBJREG.DATE正则,就会显示OBJREG["prompt"].date对应的提示文字内容。

您还可以自定义HTML5规范以外的type, 例如插件自带的type=zipcode邮编验证就是自定义的。

类似的,您网站的昵称等也可以自定义,例如type="nickname", OBJREG对象如下扩展即可:

昵称
<input type="nickname" class="nickname" required data-min="6" data-max="20" /> 6-20个单词字符
<a href="javascript:" class="button">检测</a>

JS部分的设置:

OBJREG.NICKNAME = "^\\w+$";
OBJREG["prompt"].nickname = "只能是字母数字以及下划线";

$(".button").bind("click", function() {
    var nickname = $(".nickname");
    if ($.html5Validate.isAllpass(nickname)) {
        alert("验证通过!");    
    }
});

于是乎,当含非单词字符的时候,就会有下图所示提示:
自定义nickname类型及对应提示截图 张鑫旭-鑫空间-鑫生活

您可以狠狠地点击这里:html5Validate全局对象OBJREG扩展demo

OBJREG对象与pattern属性之间关系
一句话,pattern权重大于OBJREG.

举个例子,有些情况下,数值输入框可以允许输入中文单位,您就可以这样处理:

<input type="number" pattern="^\d+" />

这样子,插件会使用pattern属性对应的正则,而不是type对应的正则。于是,您输入”10人”就不会提示你“请输入数值”。

注意:pattern属性对应的正则中的斜杠(\)等无需转义,但是,如果是OBJREG对象表示,则需要转义(\\)!

十、各类实际应用

1. 注册及其验证
您可以狠狠地点击这里:html5Validate下注册以及验证demo

这个demo在demo里面算是蛮仿真的,验证码以及验证什么的都是有处理的。

值得说明的
① 昵称有个模拟Ajax验证的处理,当输入5个合法字符的时候,会提示“该昵称已存在”。
该昵称已存在提示截图 张鑫旭-鑫空间-鑫生活

其中,使用了前面提到的$.testRemind.display以及$.html5Validate.isRegex(ele).

② 确认密码框禁用与不禁用的控制部分有这么一行代码:

if ($.html5Validate.isEmpty(this)) {

$.html5Validate.isEmpty前面曾一笔带过,其用来检测输入框值是否为空,非password类型输入框会过滤前后空格。

③ html5Validate插件并没有密码或手机号码前后一致验证的方法,如果在实际使用中遇到这类需求,您可以在html5Validate验证回调中进行额外验证。
回调与额外验证 张鑫旭-鑫空间-鑫生活

2. 发表点评及验证
您可以狠狠地点击这里:html5Validate发表点评及验证demo

html5Validate插件实例之发表点评验证截图 张鑫旭-鑫空间-鑫生活

这个demo的重点就在星星的处理上。

星星的本质是单选框组,从差到好共5个单选,默认是显示的,当JS执行到此的时候,单选框组隐藏,默认隐藏的星星们显示;这个交互就是我上面提到的模拟表单!

单选框组的验证只有”是否必选”这1条,如果必选,则仅仅1个单选required即可,理论上是无论哪个都行。规范与统一期间,我们可以约定同组第一个radio设置required. 再由于这里的radio被模拟,因此,这个有required属性的单选框必须隐藏(display:nonevisibility:hidden),否则,提示文字的位置为指向这个看不见的单选框。

该单选框HTML代码如下:

<input type="radio" id="radioImp1" name="impress" value="1" required data-target="starScore"><label for="radioImp1">差</label>

然后通过:

$().css("visibility", "hidden");

将其隐藏不可见,打通任督二脉,以便data-target的乾坤大挪移招数可以发起来!于是,我们就看到了上图中“提示框指向星星”的画面。

点击星星的操作实际是让对应单选框选中,从这点来看,我们还可以把星星使用label标签表示, 这样,连选中的JS代码都可以省了。呵呵~~

其他都是些常规验证,没有什么好说的。

十一、结语以及其他杂碎

IE10向下兼容模式的IE6-IE9, 其HTML5表单属性又有严重的冲突bug(外表看不出来). 因此,本插件在这些浏览器下有部分的不支持,主要是IE10支持的HTML5 type类型,具体可参见前面一篇文章:“IE10↘IE7-IE9 type=email的完全抛弃”。

我个人的建议是忽略之,理由略……如果您实在想支持,email/tel/url/number这几种type后面加一个空格即可!在参数novalidatefalse的时候,本插件会自动把后面的空格给remove掉的,并不影响正常的HTML5表单功能。

本插件验证机制多遵循Chrome浏览器,因此,其表单验证都是一个一个提示的,大范围标红这种需求本插件满足不了。

补充:关于即时验证
我去年这个时候写了篇讨论JS前端验证的文章“JS前端验证与用户自由思想”。我不喜欢跟风,我对即时响应验证是相当不感冒的,推崇结果为导向的验证。这些想法不是凭空YY出来的,而是借鉴与参考了Google以及Chrome浏览器。因此,像这种可以很好推广自己想法的机会,自己是不会让插件支持即时响应验证的。同时即时验证意味着要对各个表单元素绑定事情,这样,岂不反而陷入了“过多干预”这个缺点,限制了用户的自由。“用户自由”是未来的趋势,this plugin designs for future!

虽然插件支持即时验证无望,但是,插件之外是可以简单几行代码支持的,如下:

$.fn.immediValidate = function(passCallback) {
    return $(this).find(":input").each(function() {
        if (/^submit|image|reset|file|radio|checkbox|button$/.test(this.type)) return;
        var self = this;
        $(this).bind("blur", function() {
            setTimeout(function() {
                if ($.testRemind.display == false && $.html5Validate.isAllpass($(self))   ) {
                     $.isFunction(passCallback) && passCallback.call(self);
                }
            }, 100);    
        });
    });
};

于是,我们只要这样绑定JS就可以了:

$("form").html5Validate().immediValidate();

本地已验证。

虽然html5Validate插件的完成细嚼慢咽,多番积累,但是,不可能面面俱到,因此,如果承蒙您使用了,并且发现了相关问题,欢迎提出来。我会尽快修改并发布的。因为github自己还玩得不熟,版本啊更新什么的都是比较传统的手动方式,所以可能会有JS是最新的,但是文中的更新日期还是落后的情况,希望见谅。

也欢迎提出其他宝贵意见,不甚感谢!

(本篇完)

分享到:


发表评论(目前111 条评论)

  1. Willie说道:

    请问有没有方法取消一块display:none区域里表单元素的验证?

  2. Muniya说道:

    使用中遇到一个很诡异的问题。
    使用 ^[a-zA-Z]{1,}$ 匹配,限定datamin为2,datamax为10,然后问题来了:
    匹配 “CT” 成功
    匹配 “CTCT”成功
    匹配 “CTA”成功
    匹配 “CTC” 失败!!!!!

    更换各种表达式,无解,就是 CTC匹配不了。。。。

    不好意思,纠结了15分钟未解决,结果发个帖子换换脑子,两分钟fixbug了。。。自身代码问题,CTC定义为默认值了,唉唉,管理员不要审核通过喲~

  3. qzzm说道:

    请问楼主 这个支持 Zepto.js 的不?

  4. fans说道:

    能否设置提示语在某个特定的地方显示(如input后的一个隐藏span,或者表单头部某个集中区域)

  5. fans说道:

    input 非 hidden的情况下。(例如:readonly)设置 data-key无效。

  6. sunny叶雨竹说道:

    引用了你的这篇文章介绍的插件,但是,在验证网址时,老板一定要那种不需要输入http://的,只有后面的那样的网址,所以不知道该怎么改,求大神赐教

  7. 功能疑问与咨询说道:

    额外验证写在 validate : 里。那么和写在html5Validate(function () {….});中有什么区别呢?
    对象的 data-* 有没有更多的配置?例如, 使用正则表达式 data-regx=”[^\d]”

  8. 关于html5Validate应用于手机app (jquery mobile)说道:

    哥 这个验证虽然在手机上能响应,不过响应弹出验证框后,貌似页面切换(jqm的页面切换方式)或者轻触摸页面其他地方,验证框一直保留着,求解

  9. 极品飞鸽说道:

    在新公司项目里面看见这个插件,百度来到这里的,博主为什么不提交到jquery官方插件库里面,这样更多的人可以使用,也可以扩大影响

  10. 上上签说道:

    大神 貌似ie8,ie9 中表单使用placeholder.js type=“password”验证信息会报错 可有解决方法,望回复! 感谢

  11. 16code说道:

    插件是非AMD规范,在require js中还要改动哦

  12. 标题验证时,全角符号被格式化为半角说道:

    标题验证时,全角符号被格式化为半角。

    例如以上这一行提交时会自动变成:

    标题验证时,全角符号被格式化为半角.

  13. 有没有ajax提交时的验证示例说道:

    经过一段时间的实践,发现在iframe里触发这个验证不会进validate,不知道是我使用错误还是插件本身有这个问题

  14. 朱俊说道:

    经度:

    chrome 41.0 ,没有设step,经度输入121.1111 保存成功,没有变成你在《HTML5 number类型文本框step属性的验证机制》中提到的“默认step为1,因此,木有step属性值的时候,小数值是无效的(.0除外)。”

    接上条,试了一下,如果不用$(“#info_form”).html5Validate(function(){。。。});,可以出来step的提示,如果用了,只会验证基本的required,不会验证step

    接,添加参数”{novalidate:false}”后,浏览器验证step 可以work,说明插件验证有bug?

  15. carlos说道:

    为什么type=”number”的时候数字的类型就不验证了

  16. javascript说道:

    有没有button下的onclick触发验证,同时可以用validate:function(){}的实例呢?好多情况下提交表单的时候还会有一些是文本值的内容要获取,submit有点死板了,我想用button先验证,然后自己写ajax提交的。

  17. k626说道:

    $(“#regform”).html5Validate(function(){}) 前后不能加其他JS代码?加了之后就没效果了?
    能不能支持自定义函数验证?

  18. bachaxianren说道:

    请问手动插入的表单元素怎么实现验证

  19. 请问说道:

    请问支持JSP,我换成JSP了没有提示信息了呢?

  20. movelift说道:

    FF:

    too much recursion
    if (document.querySelector) {
    ….

  21. test说道:

    建议加上电话号码,网址(http|https),及身份证格式的校验,这样的使用情况还是比较多的!

  22. test说道:

    给你提个BUG吧。178行少个逗号(attrDataMax后面):
    var attrMin = $(ele).attr(“min”), attrMax = $(ele).attr(“max”), attrStep
    // 长度限制
    , attrDataMin, attrDataMax,
    // 值
    value = ele.value;

    会导致data-max设置的值在验证时,超过该值就不验证后面的项了,直接提交了!

  23. Chvin说道:

    type=”radio”在设置required时,设值后取值为空,导致不能提交。
    我已经发邮件到将问题demo,和修改发你邮箱 🙂
    PS:页面几个demo引用的douban JQ文件 失效了~

  24. king说道:

    jsp页面不能用吗?应该可以的吧,是不是有什么注意的地方。

  25. movelift说道:

    textarea: data-max 限制超出时,验证出错:use strict
    (Firefox 28.0)

  26. movelift说道:

    1、不知为何


    验证不通过。选中了还提示要选。

    2、 immediValidate: foucs 与 blur 死锁。焦点不能离开……

  27. Ted说道:

    1.发现了一个家伙在copy你的文章额?
    http://space.nerc-edu.net/u/%E9%9B%B7%E6%B0%B8%E5%B3%B0/Blog.aspx/t-4743
    2.你的插件还在更新吗?
    3.对ie8兼容好吗?

  28. ReferenceError: html5Validate is not defined说道:

    已经在网页头部引入了jquery-html5Validate.js?v=14文件,但是在提交的时候会报错:ReferenceError: html5Validate is not defined。

    在网上没有找到答案,还请您指点迷津啊。小弟不胜感激

  29. checkbox验证不了说道:

    代码323行: } else if (type == “checkbox” && isRequired && !$(el).attr(“checked”)) {
    // 复选框是,只有要required就验证,木有就不管
    !$(el).attr(“checked”)这个是取不到值的,可改为!$(el).is(“:checked”);

  30. movelift说道:

    能否页面内的任何地址查询某个字段是否通过难? 例如:手机号输入正确后才可以点击“获取验证码”

  31. 动次大次说道:

    博主,好像都不支持IE哦,
    例如:http://www.zhangxinxu.com/study/201212/html5validate-example-comment.html
    请问如何解决,谢谢

  32. bbca说道:

    1.index.html 页面内容

    用jquery ajax 调用另一个包含html5Validate验证的页面

    $.post(‘page.php’, {index:4}, function (data){
    $(“#xpage”).html(data);
    });

    二. page.php页面内容

    $(“#btn”).bind(“click”, function() {
    var nickname = $(“.nickname”);
    $(“#nickname”).testRemind(“昵称是空的!”);

    });

    报错是:

    TypeError: $(…).testRemind is not a function

    (47 out of range 5)

    中用ajax引用一个

  33. 吴春华说道:

    您好,您的代码很方便,但是我发现了一些问题。
    现象为:一个表单中有多个form,而验证使用 $(‘form’).html5Validate时检验会出问题。

    我查看了一下源代码,发现在初始化的时候将elements设置为了$(this).find(“:input”),这样当我只需要验证某一个form的时候因为初始化时将elements设置为了所有form的input 而验证了所有input。我简单的将elements的初始化放到了 submit事件的处理当中后运行良好。

  34. 李晓志说道:

    我在使用中,觉得其实不需要使用lableDrive,只要把placeholder当成提示信息就可以了,所以,我在237行添加了如下内容:
    }else{
    text=$.html5Attr(control, “placeholder”);
    }
    我觉得这样就很方便了,您说呢?

  35. scgy5555说道:

    数值文本框的UI的部分
    确实用 number| 会识别不出而变成普通的input type=”text”
    但验证过后 就变成number了 非常丑的增减按钮又跑出来了

  36. jason说道:

    找了很长时间了,终于找到了,首先谢谢你.
    我有一个问题,在项目验证checkbox时,一般是在多个选择项里,只要选择其中的几项(可由一个参数来指定具体的数字,如10个可选项中只要选择其中3项即可)就可以了,而不是必须选择某项,不知博主如何看待这个问题?

    • 张 鑫旭说道:

      @jason 就你这个问题,我更新了下插件,新增参数validate, 值为一个验证函数,专门验证插件不能完成的验证,例如你这里所说的可选项选3个。还有demo,这里:http://www.zhangxinxu.com/study/201306/jquery-html5validate-plugin-validate-params.html

      • jason说道:

        非常感谢,果然好用.
        还有一个问题,由于我没有使用ajax提交,我直接在form的最下边用

        $(“#frm”).html5Validate();

        来为表单增加验证,当点击提交按钮时,在你源码的552行处的callback.call(this);报callback无定义,所以我做的小修改
        if ($.html5Validate.isAllpass(elements, params)) {
        if(typeof callback === “function”){
        callback.call(this);
        }
        }

  37. 友赛尔说道:

    恩。谢谢你。type 限制这里,我知道需要怎么用参数。明白你的意思了。谢谢哈

  38. 友赛尔说道:

    type为text 的时候,min 和max数值验证字符数呢?例如会员名允许中英文混杂类似淘宝限制了5-25字符。而目前机制3个中文也小于5字符了。。。理论上3个中文应该等同6个英文或者符号哈?不熟JS实在改不成能应用的了。特来求教。

    • 张 鑫旭说道:

      @友赛尔 你好,type为text 的时候,min 和max数值不能字符数,不过可以使用data-maxdata-min, maxmin是用在number类型中数值大小限制,不是个数。还有,目前并未提供中文算作两个字符的接口,我也不会添加。你需要做插件以外的验证。

  39. 张 鑫旭说道:

    大家好

  40. buhuiyonga说道:

    引用jQuery框架,示意:

    引用html5Validate插件,示意:

    绑定调用:
    $().html5Validate(callback, options);
    示意,假设测试表单id为html5Form,则有:
    $(“#html5Form”).html5Validate(function() {
    // 全部验证通过,该干嘛干嘛~~
    });

    按照以上三步 无效果啊!!!!

  41. shooke说道:

    在演示页面拖动部分,ie下拖动后隐藏域无法赋值,我用的ie8. chorme和ff都没问题

  42. 老猫说道:

    小张你太牛了,现在每天开你网站学习,已经成为一种习惯。

  43. ipoly说道:

    个人觉着单选框的required可以判断为该组应该有选中吧。有时候就是有那么蛋疼需求,单选框组没有默认项,非要手动选一个。

  44. Nightwing说道:

    注意:提示框出现后,点击提示框以外的页面任意位置,或在表单元素foxus状态下触发键盘,或改变浏览器的尺寸,提示框都会因此。

    最后的“因此”应该是被输入法强奸了吧!

  45. 小克说道:

    您的源码是用的啥编码?UTF-8搞出来的都是乱码啊……

  46. Zz说道:

    实在是太强大啦!正好用到!!感谢张鑫旭!

  47. AlphaTr说道:

    貌似 radio 和 checkbox 时有三角的遮挡,如图:http://ww1.sinaimg.cn/large/5cfbe76ejw1e00cpi0mukj.jpg

  48. unicac说道:

    要是能实时验证就爽了!

  49. hyf说道:

    请教博主一个疑问,验证插件的demo页面都是以from表单提交并跳转到其他页面,如果希望以ajax方式提交,应该怎么调用您的验证插件啊?

    • 张 鑫旭说道:

      @hyf html5Validate就是为ajax提交设计的,第一个demo就是Ajax提交的,只是为了明显表示提交成功,在Ajax成功后提交了表单。

  50. VVG说道:

    要提交了才验证吗