`

jQuery学习之:Validation表单验证插件

阅读更多
最近由于公司决定使用AJAX + Struts2来重构项目,让我仔细研究一下这两个,然后集中给同事讲讲,让每个人都能够有所掌握,慢慢会用。于是,自己便开始学习……

由于Struts2自己早就学过,因而不需要花多少时间。而AJAX之前没怎么用过。现在AJAX框架如此之多,选择哪一个呢?开始打算选择dojo,但是看了一点后,发现蛮复杂的。在之前有学过一点点jQuery,而网上也说jQuery很强大而且很容易上手。对于我这种情况,正需要上手快的产品。于是,决定选择jQuery。网上jQuery相关的资料很多,如果想学习jQuery,我个人觉得《锋利的jQuery》蛮不错的,推荐看看。

快速的学习完jQuery的基础知识后,便开始做Demo。这时发现一个问题:有些功能反复使用,能不能提取出来?既然我遇到了这样的问题,其他人肯定也遇到了。而jQuery的插件功能如此强大,肯定有相关好用成熟的插件可以使用。于是上网搜到了几个。这篇文章首先跟大家分享一下validation表单验证插件的使用心得。(注:有些来自于网上,在此无法列出作者,请见谅!)

我们都知道,提供客户端验证有很多好处,最重要的好处,我觉得就是能够让用户及时的知道自己填写是否正确,这样是很友好的。软件界有这么一句话:错误发现的越早,损失就会越少……因而,对于WEB开发,表单验证是必不可少的。

说到客户端验证,当然离不开javascript,然而,使用单纯使用javascript有不少问题:1、冗余的代码太多;2、要考虑浏览器的兼容问题;3、工作量大。这几个方面,笔者在项目中深有体会。之前,未进入公司工作时,总觉得公司编码会多么多么的规范,进去之后,发现根本不是这么回事。(当然,有些公司可能还是蛮规范的。)就拿我最近做的项目来说吧,我感觉代码实在是太差了,简直可以用惨不忍睹来形容。其中之一就是代码很不规范,完全就是为了实现功能,我有时跟同事开玩笑:这样的代码,只有自己能看懂吧……当然,不规范最严重的就是页面代码。一个jsp文件中,什么代码都有:java,jsp标签,struts标签,css,javascript等,总之能有的都有,不应该有的也有。其中最糟糕的是:同一个jsp文件中,javascript代码有写在外部js文件中的,有写在jsp文件的<head>中的,有写在<body>中的,还有写在文件最后的。我看了之后很无语。记得又一次,我看他们写的代码,在一个外部js文件中发现有一个变量根本没有定义赋值,很是奇怪,半天没弄明白。一问,他告诉我:在jsp文件的最后有定义那个全局变量……晕。当然,之所以出现这样的情况是多方面得原因,并非同事水平不行,他们一般水平都比我高。还有,现在的项目根本没法在其他浏览器访问,只能IE。正因为如此,我才建议应该重构。说了这么多,目的只有一个,那就是在应用中,我们应该考虑多方面,同时规范编码。同时,有些东西是重复的,为了提高工作效率,我们应该使用一些成熟的框架。下面就讲讲validation的相关知识。

一、validate是jQuery的一个表单验证插件,它不仅实现了客户端表单的多种验证规则,而且,还是用ajax实现了服务器端远程验证。它内置有多种验证规则,同时,可以很方便的定义自己的规则。在此,说明一些常用的功能,详细的介绍,可以参考官方文档。http://docs.jquery.com/Plugins/Validation

validation插件使用很简单:
$("#formId").validate(   
{   
        // 验证规则   
    rules:   
    {},   
    // 验证提示信息(失败时)   
        message:{},   
    errorElement: 'span',                       // 放置错误信息的元素,可以是其他的。   
    errorPlacement: function(error,element)     // 将错误提示信息放在什么地方   
    {},   
        // 成功时执行   
    success: function(label)   
    {   
        label.text(" ")                     // 将错误内容清空,一定要是" "有空格,否则IE有问题。   
            .addClass("success");   
           
    }   
});  

其中"formId"是表单的form元素的ID属性。

rules和message分别都对应一个对象,该对象只包含属性,其中,属性名为表单中input的name(包括select的name),值为要应用的规则对象。如:
rules:{   
    userName:{   
        required:true,   
        maxlength:20,   
        emote: {   
             url: "ajax/validateUserName.action",     //后台处理程序   
             type: "post",               //数据发送方式   
             dataType: "json",           //接受数据格式      
                data: {                     //要传递的数据,默认已传递应用此规则的表单项   
                   email: function() {   
                      return $("#email").val();   
                }   
        }   
    }   
}  


message对应是一样的,只是把规则的值改为提示信息,如:required:‘必填项'。

validation内置的验证规则如下:

   required:true 必填

  minlength:最小长度

  maxlength:最大长度

  rangelength: [3,10] 长度介于 3 和 {1} 之间的字符串

  range:[100,1000] 只能是100和 1000 之间的值”

  min:最小值

  max:最大值

  email:true 验证邮箱

  url:true 验证是否是合法的网址

  date:true 验证是否是合法的日期 new Date() 类型格式

  dateISO:true 验证是否是合法的日期 年/月/日 或 年-月-日 格式

  number:true 验证是否是合法的数字

  digits:true 验证是否为整数

  creditcard: 验证合法的信用卡号

  equalTo:”要匹配的元素” 如:’#cnfpass’ , 验证两次输入值是否相同

  accept: “gif|png|jpg” 验证是否是合法后缀名的字符串
  remote: {
    url: "ajax/validateUserName.action",     //后台处理程序
    type: "post",               //数据发送方式
    dataType: "json",           //接受数据格式   
    data: {                     //要传递的数据,默认已传递应用此规则的表单项
        email: function() {
            return $("#email").val();
        }
    }

注意:remote是远程验证:比如注册验证用户名是否已被注册,返回值只能是true(验证成功)或false(验证失败)。

除了内置的验证规则,validation还允许自定义验证规则。这是通过validation的addMethod方法实现的,语法为:jQuery.validator.addMethod("name",function,message)。其中name为验证规则的名称,function定义验证的规则,message是验证失败时的提示信息。如:

jQuery.validator.addMethod("ip", function(value, element) {   
    return this.optional(element) || (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.test(value) && (RegExp.$1 < 256 && RegExp.$2 < 256 && RegExp.$3 < 256 && RegExp.$4 < 256));   
  }, "Please enter a valid ip address.");   
  // 增加只能是字母和数字的验证   
  jQuery.validator.addMethod("chrnum", function(value, element) {   
    return this.optional(element) || (/^([a-zA-Z0-9]+)$/.test(value));   
  }, "Please enter a valid format(charactors, A-Z, a-z, 0-9 only).");   
/**  
     * 自定义验证规则——对电话号码进行验证  
     */  
    $.validator.addMethod(   
        "isPhone",    
        function(value, element)    
        {      
            // “/\(?0\d{2,3}[) -]?\d{7,8}/”匹配电话号码的格式多种:010-82839278、(010)82839278、01082839278等,但是,这样有一个问题   
            // 如:(01082839278这样的也会匹配。当然可以用分支条件"|"解决,比较麻烦。而且以什么开始或结束也没有匹配。   
            // 为了简单起见,去掉有"()"的形式。匹配区号3位,则本地号8位,区号4位,则本地号7位的号码。   
            var tel = /^0\d{2}[-]?\d{8}$|^0\d{3}[-]?\d{7}$/;   
            return this.optional(element) || (tel.test(value));   
        }   
        , "电话号码格式不对."  
    );   

还可以定义其他的验证规则。应用自定义的规则很容易,自定义规则和内置规则用法是一样的。

在此,提供一个有用的验证规则,那就是针对select下拉框的验证:

/**  
     * 自定义验证规则——增加对select的验证  
     */  
    $.validator.addMethod(    
        "selectNone",               // name验证方法名   
        function(value, element)    // 验证规则   
        {   
            if (value == "none")    // select默认值需要设置为"none"(当然可以自定义其他值)   
            {    
                return false;    
            }    
            else    
            {   
                return true;    
            }   
        },    
        "必须选择一项"    // 默认验证消息(自定义规则信息的国际化是否不起作用?)   
    );   


二、验证信息的国际化

验证信息国际化是很方便的,默认验证信息是英文的,只需导入validation已写好的国际化文件,如:
<script type="text/javascript" src="scripts/jQuery/plugins/jquery.validate.js"></script>

<script type="text/javascript" src="scripts/jQuery/plugins/jquery.validate.messages_cn.js"></script>

在验证时,去掉message,提示信息就会变成中文。

可以改国际化文件中的提示信息内容,使其更加个性化、符合项目要求。另外,如果在验证时使用了message,message中指定的字段提示信息会覆盖国际化文件中的信息。

这里有一个问题,国际化时似乎没法根据浏览器的locale来自动识别该用什么语言来显示。笔者测试了一下,当导入多国语言文件时,总是会使用最后一次导入的语言。因此,要实现真正的国际化,可以通过一个链接之类的来选择语言,然后用javascript来导入不同的语言文件。

三、远程验证

远程验证很有用,用户体验很好,因为不需要提交表单就知道自己注册用户的是否已被注册。validation插件通过remote规则来实现验证。在此讲解一下如果将请求提交给struts2的action来验证。

remote规则的格式为:
 remote: {
    url: "ajax/validateUserName.action",     //后台处理程序
    type: "post",               //数据发送方式
    dataType: "json",           //接受数据格式   
    data: {                     //要传递的数据,默认已传递应用此规则的表单项
        email: function() {
            return $("#email").val();
        }

}

由于remote规则只允许后台返回true或false,因此struts2的action得不同于一般的action,不能返回一个字符串,然后dispatch一个视图之类的。研究之后,发现struts2中有一种result类型:stream,通过该类型可以实现返回true或false。action代码如下:
view plaincopy to clipboardprint?
// 定义返回的输入流   
    private InputStream inputStream;   
       
    // 定义需要到远程验证的字段   
    private String userName;   
    private String email;      
       
    // 定义返回值:只能为Boolean类型   
    private Boolean valid;   
       
    /**  
     * Action执行的方法:实现远程验证,将业务逻辑交给后台处理,并接收结果  
     * 同时,将结果返回。  
     * @return  
     */  
    public String execute()   
    {   
        // 根据userName判断该SP/CP是否已被注册;根据email判断该账号是否已被占用   
        if(spcpPreApprovalService.existSpcpAccount(userName, email))   
        {   
            valid = false;   
        }   
        else  
        {   
            valid = true;   
        }   
           
        inputStream = new ByteArrayInputStream(valid.toString().getBytes());   
           
        return Action.SUCCESS;   
    }   
    // 省略getter、setter  


struts.xml文件的配置为:

<package name="ajax" namespace="/ajax" extends="struts-default">
    	<action name="validateSpId" class="validateSpcpAction">
    		<result type="stream">
    			<param name="contentType">text/html</param><!-- 默认为text/plain -->
    			<param name="inputName">inputStream</param><!-- 默认就为inputStream -->
    		</result>
    	</action>
    </package> 


这样便可以实现远程验证功能。

总结

可以看出validation使表单验证变得很容易,实现起来很轻松。validation插件还有其他一些功能,需要了解可以查看官方文档。

由于写的demo是把公司项目的一些页面改为ajax+struts2,所以在此不方便把所有的代买贴出来。如果遇到什么问题,可以联系我。
分享到:
评论
32 楼 polaris1119 2010-10-11  
jngxx 写道
提示信息只能显示在控件旁边,能否支持用alert弹出提示信息?

有这样的需求?弹出来用户会感觉很恶心吧。你可以查官方说明文档,应该有吧。
31 楼 jngxx 2010-10-10  
提示信息只能显示在控件旁边,能否支持用alert弹出提示信息?
30 楼 zxingdream 2010-10-05  
感觉验证提示太简单了 还不允许多类型错误信息提示,不是很好用哦
只是自我感觉,嘿嘿
29 楼 qys2010 2010-09-24  
我提个问题,像 下拉框 选值的时候,怎么定义rules,使得不能选中 '未选择' 这个选项呢?
28 楼 qys2010 2010-09-24  
我的QQ:2696584,谢谢。
27 楼 qys2010 2010-09-24  
怎么联系你啊,我最近项目里也尝试用jquery
26 楼 qys2010 2010-09-24  
不错啊,写的
25 楼 wangking717 2010-09-19  
总觉得Validation用的JS配置太多了,使用者往往要写一大堆的JS代码。建议大家有空可以去看看EasyValidator
http://wangking717.iteye.com/blog/765772
24 楼 polaris1119 2010-06-26  
kieslowski 写道
比如第一行是银行账户号码,第二行是银行名字,验证第一行的银行账户在第二行的银行中存在
/123-456-789 在工行是个合法的帐号,但/123-456-789在招行就不存在这个帐号。
我的jquery validation 验证是绑定在账户上的,用户第一次输入[123-456-789,工行],验证通过,然后改为[123-456-789,招行],希望能得到验证失败。但这个时候俺绑定在第一行的验证根本不会触发,因为已经验证通过了,而且用户没改动帐号。


我给你两种建议,你参考参考:
1、为什么你要绑定在账号上呢?绑定到银行上不是更好吗?这样的话:输入账号时不验证,因为不知道是哪个银行的,也没法验证。然后输入银行时,根据这两个参数去验证。这样,当每次更改银行时都会去验证了。当然,这样还是会有一个问题,就是修改账号时,不回去验证,你跟遇到的情况一样。这时候,你可以通过js,用ajax去后台验证。
2、如果觉得第一种太麻烦,想全部用validation插件做,可以这样。两个表单项都绑定验证,每次验证时在后台进行一个判断,如果这两者有一个是空,则让其验证通过,这样做是避免第一次输入账号时就验证不成功。我想这两项应该都不允许为空的吧,至少不能而着之一为空。你看看这样有没有漏洞。

你试试,有问题再讨论
23 楼 kieslowski 2010-06-23  
比如第一行是银行账户号码,第二行是银行名字,验证第一行的银行账户在第二行的银行中存在
/123-456-789 在工行是个合法的帐号,但/123-456-789在招行就不存在这个帐号。
我的jquery validation 验证是绑定在账户上的,用户第一次输入[123-456-789,工行],验证通过,然后改为[123-456-789,招行],希望能得到验证失败。但这个时候俺绑定在第一行的验证根本不会触发,因为已经验证通过了,而且用户没改动帐号。
22 楼 polaris1119 2010-06-21  
kieslowski 写道
还有个问题比较棘手,某个验证需要2个字段参与,因为是remote验证,用户输完field1 就运行,发现field2 还没值,就return true了,然后validation框架把它标识为valid。等用户填完field2,submit form的时候根本不会重新检查field1,除非 field1 发生变化

field1 有值 field2必须要有值这个验证也有,但是非remote的,会等到submit form的时候才触发,比remote晚了半拍

最根本的两点:
1) 为啥remote事件提前运行,而不是等到submitform再跑
2) field1 值不变,框架会一直认为他是valid的,不去再跑一次验证。但是其实field2 值的变化也会导致业务上通不过验证。如何让框架再这种情况下重新跑field1上的remote验证?

http://groups.google.com/group/jquery-en上不去,真杯具啊

你这是啥应用场景,不是很明白你的意思。
http://groups.google.com/group/jquery-en我也上不去,上面有啥?上去干嘛?
21 楼 kieslowski 2010-06-21  
还有个问题比较棘手,某个验证需要2个字段参与,因为是remote验证,用户输完field1 就运行,发现field2 还没值,就return true了,然后validation框架把它标识为valid。等用户填完field2,submit form的时候根本不会重新检查field1,除非 field1 发生变化

field1 有值 field2必须要有值这个验证也有,但是非remote的,会等到submit form的时候才触发,比remote晚了半拍

最根本的两点:
1) 为啥remote事件提前运行,而不是等到submitform再跑
2) field1 值不变,框架会一直认为他是valid的,不去再跑一次验证。但是其实field2 值的变化也会导致业务上通不过验证。如何让框架再这种情况下重新跑field1上的remote验证?

http://groups.google.com/group/jquery-en上不去,真杯具啊
20 楼 select*from爱 2010-06-01  
bencode 写道
可以试用一下我的验证框架,我一直用这个:)

它有以下特点:
1. 不依赖于其他库
2. 不需要编写JS代码就能完成常见的验证任务
3. 可以扩展内置验证器
4. 可以扩展错误提示展现方式
5. 没有名字空间冲突

http://bencode.iteye.com/admin/blogs/349204

120k 好大
19 楼 kieslowski 2010-05-29  
楼上的建议跟这里
http://forum.jquery.com/topic/jquery-validate-invalidhandler-question 非常类似
18 楼 polaris1119 2010-04-14  
kieslowski 写道
几个问题:
1) 如何定义多个validator的执行顺序,在执行链某个步骤没pass,下面的都不执行?比如验证金额是合法字符后才去后台做业务相关的验证,不重复前面验证的代码可以吗?
2) 如何获得验证后的标志位,pass or not pass, 在pass 后对UI做某些操作

默认会把所有validator跑一遍的。如果ajax验证多,会发很多XMLhttpRequest



你可以参考:http://docs.jquery.com/Plugins/Validation上的文档。
可以看看:
invalidHandler和showErrors这两个回调函数,看能不能满足你的要求。
还有element(element)方法用于验证单独的一个,可以试试。
numberOfInvalids()方法获得失败的表单个数。
17 楼 hay 2010-04-07  
刚好之前我也做了个项目是Struts2+Ajax来实现的。。不过我用的是JQuery EasyUI来弄的。。。你用的那个我也有研究,也用了,哈哈。不过我更期待EasyUI希望它能更强大
16 楼 kieslowski 2010-04-06  
几个问题:
1) 如何定义多个validator的执行顺序,在执行链某个步骤没pass,下面的都不执行?比如验证金额是合法字符后才去后台做业务相关的验证,不重复前面验证的代码可以吗?
2) 如何获得验证后的标志位,pass or not pass, 在pass 后对UI做某些操作

默认会把所有validator跑一遍的。如果ajax验证多,会发很多XMLhttpRequest
15 楼 bencode 2010-01-03  
可以试用一下我的验证框架,我一直用这个:)

它有以下特点:
1. 不依赖于其他库
2. 不需要编写JS代码就能完成常见的验证任务
3. 可以扩展内置验证器
4. 可以扩展错误提示展现方式
5. 没有名字空间冲突

http://bencode.iteye.com/admin/blogs/349204
14 楼 myheart 2009-12-31  
现在 也在  看这个方面的  以前稍有接触
13 楼 polaris1119 2009-12-30  
pingjing 写道
有没有方便的服务器端的验证啊?

服务器端,你用的啥?struts1.x还是struts2或者其他?如果是struts1.x的话有Apache的commons-validator,struts1.x集成了的。如果是struts2的话,有xwork的validate,struts2也是集成了的。这两个其实差不太多,都是通过配置文件实现的。另外,你也可以通过实现validate()方法:struts1.x是在FormBean中,而struts2则是在action中。

相关推荐

Global site tag (gtag.js) - Google Analytics