【问题标题】:jQuery Validate - Add Error Class to Parent DivjQuery Validate - 将错误类添加到父 Div
【发布时间】:2011-12-18 00:08:04
【问题描述】:

我正在使用 jQuery Validate 插件,但始终找不到显示复选框错误的好方法。如果未选择任何复选框,我想以红色突出显示所有复选框标签,并决定通过向包含复选框和复选框标签的 div 添加一个错误类来执行此操作。但是,它似乎没有添加类。我没有正确选择 div 吗?

HTML:

<div class="left-aligned indent">

    <label id="id_label" for="id" class="label">Items:</label>

    <div class="select-group">

        <input type="checkbox" name="items" value="1" id="item_1" />
        <label class="checkbox">Item #1</label><br />

        <input type="checkbox" name="items" value="1" id="item_2" />
        <label class="checkbox">Item #2</label><br />

        <input type="checkbox" name="items" value="1" id="item_3" />
        <label class="checkbox">Item #3</label><br />

    </div>

</div>

Javascript:

$().ready(function() {

    $('#addForm').validate({
        rules: { 
            "items": { 
                required: true, 
                minlength: 1 
            } 
        }, 
        errorPlacement: function(error, element) {
            if (element.is(':checkbox')) {
                $(this).prev("div").addClass('checkbox-error');
            }
            else {
                 return true;
            }
         }
    }); 


});

CSS:

.error {
    background-color: #FF898D;
    border: 1px solid #000;
}

.checkbox-error {
    color: #FF898D;
}

【问题讨论】:

    标签: javascript jquery css jquery-validate


    【解决方案1】:

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

    访问验证器设置

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

    1. 在为所有表单加载表单之前调用jQuery.validator.setDefaults()
    2. 通过传入.validate([options]) 上的选项来初始化表单时
    3. 通过在表单上使用$("form").data("validator").settings 定位验证器对象进行初始化后

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

    覆盖默认行为

    我们要修改的默认方法是highlight 和unhighlight,它们将分别高亮无效字段或恢复高亮选项所做的更改。这是他们的默认行为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. 包装这些函数并像往常一样调用它们,但在之前或之后添加您自己的自定义代码。

    选项 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 函数方面,有几个示例 here、here 和 here)。这是其中之一的解析示例,这将有助于在函数调用之间绑定 this 上下文,保留传递的参数的数量,并保留返回值:

    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】:
      $(element).parent('div').addClass('checkbox-error');
      

      【讨论】:

      • 似乎仍然无法正常工作。当我签入 Firebug 时,它仅将 class="error" 添加到第一个复选框。
      • 知道了,'this' 应该是'element' $(element).parent('div').addClass('checkbox-error');
      • 啊,但是现在当一个复选框被选中时,这个类并没有被删除,它仍然是红色的。选中复选框后,如何从 div 中删除类?
      • 我认为 stackoverflow.com/a/17211258/923785 应该是公认的答案 - 在字段更改为有效后,上述内容将错误类抛在脑后。
      • 如果我使用上面的脚本,自定义消息将被删除
      【解决方案3】:

      这应该可行:

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

      查看文档了解更多选项:

      【讨论】:

      • 这确实应该是公认的答案 - 这确保了自定义类在验证状态发生变化时被应用和删除。即使字段已更改为成功验证,接受的答案也会留下错误类(此处突出显示stackoverflow.com/questions/7941662/…)
      猜你喜欢
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      相关资源
      最近更新 更多