jQuery Validate:向父div添加错误或验证类

时间:2012-05-03 13:01:52

标签: jquery validation jquery-validate twitter-bootstrap

我使用Twitter的Bootstrap作为我正在进行的项目的框架。我试图使用jQuery Validate插件验证一个简单的联系表单,但它引起了一些麻烦。

我希望将错误有效类添加到每个表单输入的父div 中。这是我的表单代码:

 <form id="msg-form" class="">
    <fieldset>
        <div class="input-prepend control-group pull-left">
            <span class="add-on">@</span>
            <input class="span3 required email" id="inputEmail" name="msg-email" type="text" placeholder="example@example.com">
        </div>
        <div class="input-prepend control-group pull-left">
            <span class="add-on"><i class="icon-user"></i></span>
            <input class="span3 required" id="inputName" name="msg-name" type="text" placeholder="Joe Bloggs">
        </div>
        <div class="input-prepend control-group">
            <span class="add-on" style="height: 53px;"><i class="icon-pencil"></i></span>
            <textarea class="span3 required" id="textarea" name="msg-comments" rows="2" style="height: 53px" placeholder="Just say hi, or tell us how we can help"></textarea>
        </div>
        <button type="submit" class="btn pull-right">Submit<i class="icon-chevron-right"></i></button>
    </fieldset>
</form> 

正如您所看到的,我的 div.control-group 是我想要将类添加到的div。我试图使用突出显示(如建议的here,但这根本不起作用)&amp; errorPlacement (见下文),但我没做错。

理想情况下,我希望在keyup上添加/删除 ,以便保留插件提供的强大功能。这个简单的代码有效,但它不会删除类和&amp;仅适用于提交表格:

$("#msg-form").validate({
    errorPlacement: function(error, element) {
        $(element).parent('div').addClass('error');
    }
});

任何人都可以建议我应该用什么方法来实现这个目标?!

提前致谢 - 我可以提供必要的任何其他详细信息!

3 个答案:

答案 0 :(得分:13)

尝试使用highlightunhighlight函数:

$("#msg-form").validate({
    highlight: function(element) {
        $(element).parent('div').addClass('error');
    },
    unhighlight: function(element) {
        $(element).parent('div').removeClass('error');
    }
});

答案 1 :(得分:1)

根据我对add class to parent div if validation error occurs using jquery validation的回答,因为我相信它可以为这个问题的现有答案增加价值......

访问验证器设置

第一项业务是修改表单验证器上的settings对象。您可以通过以下任何方式执行此操作:

  1. 在通过调用jQuery.validator.setDefaults()
  2. 为所有表单加载表单之前
  3. 通过传递.validate([options])
  4. 上的选项初始化表单时
  5. 通过使用$("form").data("validator").settings
  6. 在表单上查找验证程序对象进行初始化

    由于您正在使用MVC,因此unobtrusive-validation将自动初始化表单,因此选项#2不可用。所以让我们继续使用选项3 - 这里的目标只是为了能够自定义表单上的设置。

    覆盖默认行为

    我们要修改的默认方法是highlightunhighlight,它们将突出显示无效字段或分别恢复突出显示选项所做的更改。这是他们的默认行为according to the source code

    highlight: function( element, errorClass, validClass ) {
        if ( element.type === "radio" ) {
            this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
        } else {
            $( element ).addClass( errorClass ).removeClass( validClass );
        }
    },
    unhighlight: function( element, errorClass, validClass ) {
        if ( element.type === "radio" ) {
            this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
        } else {
            $( element ).removeClass( errorClass ).addClass( validClass );
        }
    }
    

    所以你在这里也有几个选择。

    1. 完全替换这些功能并自行编写
    2. 包装这些功能并像平常一样调用它们,但在之前或之后添加您自己的自定义代码。
    3. 选项1 - 替换批发

      这条路很容易。只要在那里写下你想要的任何东西。也许来自源代码的种子,也许做自己的事情。

      var valSettings = $("form").data("validator").settings
      valSettings.highlight = function(element, errorClass, validClass) { ... }
      valSettings.unhighlight = function(element, errorClass, validClass) { ... }
      

      选项2 - 换行功能

      这种侵入性较小,因此在大多数情况下可能更为可取。

      由于最终您将替换valSettings.highlight的值,因此您需要访问原始函数的干净原始版本。您可以保存自己的或从全局默认值中抓取一个

      // original highlight function
      var highlightOriginal = $("form").data("validator").settings.highlight;
      var highlightDefaults = $.validator.defaults.highlight
      

      在包装JavaScript函数方面,有几个示例hereherehere)。以下是其中一个示例的解析示例,它将帮助跨函数调用绑定this上下文,保留传递的参数的arity,并保留返回值:

      function wrap(functionToWrap, beforeFunction) {
          return function () {
              var args = Array.prototype.slice.call(arguments),
              beforeFunction.apply(this, args);
              return functionToWrap.apply(this, args);
          };
      };
      

      然后,您还必须快速定义在调用时要触发的任何其他行为。在这种情况下,让我们找到与元素最接近的父div并更新它的类,如下所示:

      function highlightDecorator(element, errorClass, validClass) {
          $(element).closest("div").addClass(errorClass).removeClass(validClass);
      }
      

      全部包装 (看我在那里做了什么)

      $(function () {
        var valSettings = $("form").data("validator").settings
        valSettings.highlight = wrap($.validator.defaults.highlight, highlightDecorator)
        valSettings.unhighlight = wrap($.validator.defaults.unhighlight, unhighlightDecorator)
      });
      
      function wrap(functionToWrap, beforeFunction) {
        return function () {
          var args = Array.prototype.slice.call(arguments);
          beforeFunction.apply(this, args);
          return functionToWrap.apply(this, args);
        };
      };
      
      function highlightDecorator(element, errorClass, validClass) {
        $(element).closest("div").addClass(errorClass).removeClass(validClass);
      }
      function unhighlightDecorator(element, errorClass, validClass) {
        $(element).closest("div").addClass(validClass).removeClass(errorClass);
      }
      

      因此,当我们结合所有上述函数时,它看起来应该是这样的:

      Stack Snippets中的工作演示和jsFiddle

      $(function () {
        var valSettings = $("form").data("validator").settings
      	valSettings.highlight = wrap($.validator.defaults.highlight, highlightDecorator)
        valSettings.unhighlight = wrap($.validator.defaults.unhighlight, unhighlightDecorator)
      });
      
      function wrap(functionToWrap, beforeFunction) {
        return function () {
          var args = Array.prototype.slice.call(arguments);
          beforeFunction.apply(this, args);
          return functionToWrap.apply(this, args);
        };
      };
      
      function highlightDecorator(element, errorClass, validClass) {
        $(element).closest("div").addClass(errorClass).removeClass(validClass);
      }
      function unhighlightDecorator(element, errorClass, validClass) {
        $(element).closest("div").addClass(validClass).removeClass(errorClass);
      }
      input.input-validation-error  {
        border: solid 1px red;
      }
      .input-validation-error label {
        color: red;
      }
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"></script>
          
      <form action="/Person" method="post">
        
        <div class="required">
          <label for="Name">Name <em>*</em></label>           
          <input id="Name" name="Name" type="text" value="" 
                 data-val="true" data-val-required="The Name field is required."/>
          <span class="field-validation-valid" 
                data-valmsg-for="Name" data-valmsg-replace="true"></span>
        </div>
        
        <input type="submit" value="Save" />
        
      </form>

答案 2 :(得分:0)

我可能错了,但看起来你需要.parents('div.control-group')而不是.parent(),这会将.error添加到错误的div而不会将BootStraps表单颜色更改为红色。

这是因为JQuery Validate试图突出显示的输入是在BootStrap所需的.control-group下面的两个.error才能生效。

$("#form").validate({
    highlight: function(element, errorClass, validClass){
    $(element).parents("div.control-group").addClass(errorClass).removeClass(validClass);
},

希望这有帮助