zoukankan      html  css  js  c++  java
  • Jquery.validate.js表单验证

    前言:表单验证是十分常见的需求。公司做运维系统需要大量的编辑/新增表单,编辑之后提交,提交前需要进行表单验证,验证成功才能发起POST请求。由于项目前端大部分是基于Bootstrap开发的,可看官网Bootstrap Validator http://1000hz.github.io/bootstrap-validator/,感觉比较容易上手。用bootstrap validator有个问题,需验证的input/select等标签的外部需要有一个<div class="form-group">包着,验证失败时给class="form-group"的div变成红色。

     1 <form data-toggle="validator" role="form">
     2   <div class="form-group">
     3     <label for="inputName" class="control-label">Name</label>
     4     <input type="text" class="form-control" id="inputName" placeholder="Cina Saffary" required>
     5   </div>
     6   <div class="form-group has-feedback">
     7     <label for="inputTwitter" class="control-label">Twitter</label>
     8     <div class="input-group">
     9       <span class="input-group-addon">@</span>
    10       <input type="text" pattern="^[_A-z0-9]{1,}$" maxlength="15" class="form-control" id="inputTwitter" placeholder="1000hz" required>
    11     </div>
    12     <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
    13     <div class="help-block with-errors">Hey look, this one has feedback icons!</div>
    14   </div>
    15   <div class="form-group">
    16     <label for="inputEmail" class="control-label">Email</label>
    17     <input type="email" class="form-control" id="inputEmail" placeholder="Email" data-error="Bruh, that email address is invalid" required>
    18     <div class="help-block with-errors"></div>
    19   </div>
    20   <div class="form-group">
    21     <label for="inputPassword" class="control-label">Password</label>
    22     <div class="form-inline row">
    23       <div class="form-group col-sm-6">
    24         <input type="password" data-minlength="6" class="form-control" id="inputPassword" placeholder="Password" required>
    25         <div class="help-block">Minimum of 6 characters</div>
    26       </div>
    27       <div class="form-group col-sm-6">
    28         <input type="password" class="form-control" id="inputPasswordConfirm" data-match="#inputPassword" data-match-error="Whoops, these don't match" placeholder="Confirm" required>
    29         <div class="help-block with-errors"></div>
    30       </div>
    31     </div>
    32   </div>
    33   <div class="form-group">
    34     <div class="radio">
    35       <label>
    36         <input type="radio" name="underwear" required>
    37         Boxers
    38       </label>
    39     </div>
    40     <div class="radio">
    41       <label>
    42         <input type="radio" name="underwear" required>
    43         Briefs
    44       </label>
    45     </div>
    46   </div>
    47   <div class="form-group">
    48     <div class="checkbox">
    49       <label>
    50         <input type="checkbox" id="terms" data-error="Before you wreck yourself" required>
    51         Check yourself
    52       </label>
    53       <div class="help-block with-errors"></div>
    54     </div>
    55   </div>
    56   <div class="form-group">
    57     <button type="submit" class="btn btn-primary">Submit</button>
    58   </div>
    59 </form>
    View Code

    一、跳过的坑

    后来没用Bootstrap Validator, 用了jquery.validate.js插件。https://jqueryvalidation.org/,接下来学习jquery.validate.js,有点懒,直接用英文,不懂的可以评论问我,我在form表单验证踩了很多坑,比较有体会……

    最开始用jquery.validate.js时,用来验证Bootstrap模态框的Form表单,妈蛋,竟然验证不了,根本没有反应。搞了很久很久,才知道是因为用模态框时,submit按钮没有放在Form表单里面,所以触发不了验证。后来改用Bootstrap Validator,尼妈,得给要验证的input/select标签外的标签(验证不通过会变红)加上class="form-group",但是加上form-group属性后我的表单样式出错了(变丑了),怎么办,我只想给这个标签加上form-group属性,但是不希望它带上form-group的样式,正所谓有名无实……我当时不懂,一直用浏览器调前端界面,然而并没有什么卵用,后来请教隔壁组做前端的PHP大神,给这个标签的class最后加上自定义的样式,覆盖前面form-group的样式,前后只花了一两分钟,顿时膜拜铭哥大佬。比如说A标签的class有两个属性class="a b"当a和b的样式有冲突是,比时a样式是margin-top:10px,而b样式是margin-top:20px,这时会选取class最后的样式,b在a的后面,当a,b样式冲突时,会优先取b的样式。具体代码现在没有,要的话明天去公司的SVN找找看……

    后来项目被我改用layer弹框,而不是模态框,老大让我做一个表单验证的接口……

    因为总不能每一个HTML文件都写那么多JS来验证Form表单。验证接口参考了老大前公司的代码(TC公司)。

    首先,页面初始化完成时,调用表单验证接口validate_interface

        <script>
            // layer.ready(callback) - 初始化就绪
            $(document).ready(function () {
                var form_obj = $("#edit_instance_data");
                validate_interface(form_obj);  // 调用包装好的接口进行表单验证与ajax请求
            });
        </script>

    封装好的表单验证接口+Ajax请求接口+关闭layer弹框接口。

    接下来用插件自带的invalidHandler得出有多少个标签不通过验证。再利用noty插件弹出提示信息。这里我简单看了noty插件,直接会用就行了。

    看我下面的代码closest是什么意思,嗯,当时我也不知道,后来去查了下JQ,知道是从当前标签一层一层外外找,直至找到。

     $(element).closest('.selectpicker')
    

    这句代码的意思是从当前标签一层一层往外找,直至找到class="selectpicker"的标签。

    看我接口的代码会发现有highlight、success 的一些方法。这主要是因些我的form表单用了bootstrap-select插件来美化select标签,但是jquery.validate.js无法验证bootstrap-select的select标签,只能在提交表单时才会验证。这是个很奇葩的坑,我跳进出很久都出不来。网上stackoverflow看了很多解决方法,也没有什么用,是我姿势不对?

    后来在一篇stackoverflow找到解决方法

    form_obj.find("select").on('change', function(e) {
        console.log($(this));
        // 手动调用select标签
        $('.form-horizontal').validate().element($(this));
    });
    

    当验证不通过时,给标签(class:my-validate)加上has-error has-feedback属性,这样标签的边框就会变红。

    $(element).closest('.my-validate').addClass('has-error has-feedback');

    当验证通过时,移除对应的样式

    label.closest('.my-validate').removeClass('has-error has-feedback');
    

    二、以下是接口的代码,希望对你有帮助:

     1 // 封装好的表单验证接口与ajax请求
     2 function validate_interface(form_obj){
     3     form_obj.validate({
     4     invalidHandler: function(event, validator) {
     5         // 验证不通过的数量
     6         var errors = validator.numberOfInvalids();
     7         if (errors) {
     8             console.log("errors", errors);
     9             var msg = errors == 1 ? "你有 1 个必填字段未填,已经加红显示." : "你有 " + errors + " 个必填字段未填,已经加红显示。";
    10             console.log("msg", msg);
    11             noty({
    12                 text: msg,
    13                 type: "error",
    14                 timeout: 1500
    15             });
    16         }
    17     },
    18     highlight : function(element) {
    19         console.log(element.tagName);
    20         $(element).closest('.my-validate').addClass('has-error has-feedback');
    21         $(element).closest('.selectpicker').selectpicker('refresh');
    22     },
    23     //验证通过的处理
    24     success : function(label) {
    25         console.log("label", label);
    26         label.closest('.my-validate').removeClass('has-error has-feedback');
    27 
    28     },
    29 
    30     submitHandler: function(form) {
    31         console.log("form", form);
    32         // ajax request after form validate true!
    33         ajax_func();
    34 
    35     }
    36 
    37 
    38 });
    39 
    40 
    41     form_obj.find("select").on('change', function(e) {
    42         console.log($(this));
    43         $('.form-horizontal').validate().element($(this));
    44     });
    45 
    46     // 点击弹出框的确认按钮调用该函数
    47     function ajax_func() {
    48         var ajax_post_url = form_obj.attr("ajax_post_url");
    49         console.log("form_msg", form_obj.serialize());
    50         $.ajax({
    51             url: ajax_post_url,   // 提交的页面
    52             data: form_obj.serialize(), // 从表单中获取数据
    53             type: "POST",                   // 设置请求类型为"POST",默认为"GET"
    54             error:function (jqXHR, textStatus, errorThrown) {
    55                 alert(jqXHR.responseText);
    56                 alert(jqXHR.status);
    57             },
    58             success: function(data) {
    59                 var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
    60                 console.log("index", index);
    61                 parent.layer.close(index);  //再执行关闭
    62                 alert("提交成功");
    63             }
    64         });
    65     }
    66 }
    67 
    68 
    69 // interface of close layer
    70 function close_layer() {
    71     console.log("layer inter close");
    72     var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
    73     parent.layer.close(index);  //再执行关闭
    74     return false;
    75 }

    验证一通过则发起ajax请求,ajax请求成功扣则关闭当前layer弹框,对layer不了解的可以看我下篇博客……

    三、自定义验证

    接下来又有个新需求,DBA腾哥要我验证表单,比如用户输入只能由字母、数字、下划线组成……还有IP地址,发须是IP的格式才能通过验证,给后台发起请求。

    这就需要自定义表单验证方法,比如你想验证文本框验证的是不是IP地址,可以自定义表单验证方法,自己写正则表达式进行匹配,匹配不通过是显示自定义的错误信息。

     1         // layer.ready(callback) - 初始化就绪
     2         $(document).ready(function () {
     3             var form_obj = $("#edit_workflow");
     4 
     5             validate_interface(form_obj);  // 调用包装好的接口进行表单验证与ajax请求
     6 
     7             var url = location.search;
     8             $("#url").val(url);
     9 
    10             // my first validator function
    11             jQuery.validator.addMethod("my_first_validator", function(value, element) {
    12                 return this.optional(element) || /^[a-zA-Z0-9_]+$/.test(value);
    13             }, "用户名只能由字母、数字、下划线组成");
    14 
    15             // my second validator function
    16             jQuery.validator.addMethod("my_second_validator", function(value, element) {
    17                 return this.optional(element) || /^[^s]*$/.test(value);
    18             }, "密码不能包含空格");
    19 
    20             // my third validator function
    21             jQuery.validator.addMethod("my_third_validator", function(value, element) {
    22                 // 正则匹配文本框的IP
    23                 return this.optional(element) || /^(s)*(([0-9]{1,3}.){3}[0-9]{1,3}(s)*)+(s)*$/.test(value);
    24             }, "ip格式不对,多个ip请用换行符分开!");
    25 
    26         });

    至此,表单验证ending,如果你是第一次了解表单验证,想必你看完这篇博客也是一脸蒙逼的,你应该看了官网,我下面选了jquery.validate.js官网我觉得我有必要记录的一部分。可以看看,不爽就自己去看官网。

    对了,还有一个坑,百度/谷哥jquery.validate.js,会出现博客园的这篇文章jQuery验证控件jquery.validate.js使用说明+中文API,当时我想自定义错误信息,网上很多方法有用如下代码的方法,但我也引入了jquery.metadata.js,然而并没有反应。fuck! 

    使用class="{}"的方式,必须引入包:jquery.metadata.js
    
    可以使用如下的方法,修改提示内容:
    class="{required:true,minlength:5,messages:{required:'请输入内容'}}"
    

    解决方法:这个问题的实质是,我要对select标签进行验证,比如该标签是必填的,那我肯定要给标签加上required=“true",但是输入内容长度要如何加在标签?用上面代码的方法是不行的!! 还有,如果你自定义了验证方法,比如前端我自定义验证IP,那我如何让标签验证时调用这写的验证方法。其实很简单,没啥技术含量。看代码,代码现在没有,明天上班再看看

    -----------------------分割线-----------------------

    四、jquery.validate.js记录

    submitHandler (default: native for m submit)

    Type: Function()
    Callback for handling the actual submit when the form is valid. Gets the form as the only argument. Replaces the default submit. The right place to submit a form via Ajax after it is validated.

    Example: Submits the form via Ajax when valid.

    $("#myform").validate({
        submitHandler: function(form) { 
            $(form).ajaxSubmit();
        }
    });

    Example: Use submitHandler to process something and then using the default submit. Note that "form" refers to a DOM element, this way the validation isn't triggered again.

    $("#myform").validate({
        submitHandler: function(form) {
            // do other things for a valid form 
            form.submit();
        }
    });

    invalidHandler

    Type: Function()
    Callback for custom code when an invalid form is submitted. Called with an event object as the first argument, and the validator as the second.

    Example: Displays a message above the form, indicating how many fields are invalid when the user tries to submit an invalid form.

    $("#myform").validate({
        invalidHandler: function(event, validator) {
            // 'this' refers to the form
            var errors = validator.numberOfInvalids();
            if (errors) {
                var message = errors == 1 
                ? 'You missed 1 field. It has been highlighted' 
                : 'You missed ' + errors + ' fields. They have been highlighted'; 
                $("div.error span").html(message);
                $("div.error").show();
            } else {
                $("div.error").hide();
            }
        }
    }); 


    success

    Type: String or Function()
    If specified, the error label is displayed to show a valid element. If a String is given, it is added as a class to the label. If a Function is given, it is called with the label (as a jQuery object) and the validated input (as a DOM element). The label can be used to add a text like "ok!".

    Example: Add a class "valid" to valid elements, styled via CSS.

    $("#myform").validate({
      success: "valid",
      submitHandler: function() { alert("Submitted!") }
    });

    Example: Add a class "valid" to valid elements, styled via CSS, and add the text "Ok!".

    $("#myform").validate({
      success: function(label) {
        label.addClass("valid").text("Ok!")
      },
      submitHandler: function() { alert("Submitted!") }
    });

    The callback gets passed two arguments:

    • label
      Type: jQuery
      The error label. Use to add a class or replace the text content.
    • element
      Type: Element
      The element currently being validated, as a DOMElement.

    ignore (default: ":hidden")

    Type: Selector
    Elements to ignore when validating, simply filtering them out. jQuery's not-method is used, therefore everything that is accepted by not() can be passed as this option. Inputs of type submit and reset are always ignored, so are disabled elements.

    Example: Ignores all elements with the class "ignore" when validating.

    $("#myform").validate({
        ignore: ".ignore"
    });
     

    highlight (default: Adds errorClass (see the option) to the element)

    Type: Function()
    How to highlight invalid fields. Override to decide which fields and how to highlight.

    Example: Adds the error class to both the invalid element and its label

    $("#myform").validate({
         highlight: function(element, errorClass, validClass) {
            $(element).addClass(errorClass).removeClass(validClass);
            $(element.form).find("label[for=" + element.id + "]")
            .addClass(errorClass);
        },
        unhighlight: function(element, errorClass, validClass) { 
            $(element).removeClass(errorClass).addClass(validClass);
            $(element.form).find("label[for=" + element.id + "]")
            .removeClass(errorClass);
        }
    })

    The callback gets passed three arguments:

    • element

    Type: Element

    The invalid DOM element, usually an input.

    • errorClass

    Type: String

    Current value of the errorClass option.

    • validClass

    Type: String

    Current value of the validClass option.

    unhighlight (default: Removes the errorClass)

    Type: Function()

    Called to revert changes made by option highlight, same arguments as highlight.

  • 相关阅读:
    一、逻辑架构与存储引擎
    三、动态SQL
    九、装饰者模式
    二、Mapper映射文件
    八、适配器模式
    测试开发系列之Python开发mock接口(二)
    测试开发系列之Python开发mock接口(三)
    html基础
    seleniumWebdriver浏览器驱动信息汇总
    用30行代码开发一个上传、下载文件的接口
  • 原文地址:https://www.cnblogs.com/0zcl/p/7341988.html
Copyright © 2011-2022 走看看