jQuery验证 - 向父级div添加错误类

18
我正在使用jQuery Validate插件,但是找不到一个好的方法来显示复选框的错误信息。如果没有选择任何复选框,我希望将所有复选框标签都突出显示为红色,并决定通过向包含复选框和复选框标签的div添加错误类来实现这一点。然而,它似乎没有添加类。我没有正确选择div吗?
<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;
}
3个回答

52

这应该可以工作:

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

查看文档以获取更多选项:


1
这真的应该成为被接受的答案 - 这确保了自定义类在验证状态更改时被应用和删除。被接受的答案将在字段成功验证后仍然留下错误类(在此处突出显示:https://dev59.com/KWsz5IYBdhLWcg3wYGoz#nSgCoYgBc1ULPQZFkCyp)。 - iamkeir

9
$(element).parent('div').addClass('checkbox-error');

似乎仍然无法正常工作。当我在 Firebug 中检查时,它只向第一个复选框添加了 class="error"。 - Michael
1
明白了,应该把“this”改为“element” $(element).parent('div').addClass('checkbox-error'); - Michael
啊,但现在当复选框被选中时,类不会被移除,它仍然是红色的。我如何在复选框被选中后从 div 中移除一个类? - Michael
2
我认为https://dev59.com/KWsz5IYBdhLWcg3wYGoz#17211258应该被接受为答案 - 上述方法在字段被更改为有效后仍会保留错误类。 - iamkeir
如果我使用上面的脚本,自定义消息将被删除。 - kva

6

以下是我在 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已经不再适用,因为 无侵入式验证 将自动初始化表单。所以我们将采取选项3,并且期望能够定制表单的设置。

覆盖默认行为

默认方法我们需要修改的是 highlightunhighlight。分别用于高亮无效字段或撤销由高亮选项所做的更改。以下是它们的默认行为,根据源代码

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函数,这里有几个例子(这里这里这里)。以下是从其中一个示例中解析出来的简化版,它将有助于绑定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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接