简体   繁体   English

jQuery Validate - 将错误类添加到Parent Div

[英]jQuery Validate - Add Error Class to Parent Div

I am using the jQuery Validate plugin, and can never find a good way to display errors for checkboxes. 我正在使用jQuery Validate插件,并且永远找不到显示复选框错误的好方法。 I'd like to highlight all of the checkbox labels in red if none are selected, and decide to do this by adding an error class to the div that contains the checkboxes and checkbox labels. 如果没有选中,我想以红色突出显示所有复选框标签,并决定通过向包含复选框和复选框标签的div添加错误类来执行此操作。 However, it doesn't seem to be adding the class. 但是,它似乎没有添加类。 Am I not selecting the div correctly? 我没有正确选择div吗?

HTML: 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: 使用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: CSS:

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

.checkbox-error {
    color: #FF898D;
}

This should work: 这应该工作:

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

Checkout the documentation for more options: 查看文档以获取更多选项:

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

From my answer on add class to parent div if validation error occurs using jquery validation because I believe it adds value to the existing answers on this question ... 从我在使用jquery验证发生验证错误时将类添加到父div的答案,因为我相信它为这个问题的现有答案增加了价值......

Access Validator Settings 访问验证器设置

The first order of business is to modify the settings object on your form's validator. 第一项业务是修改表单验证器上的settings对象。 You can do this in any of the following ways: 您可以通过以下任何方式执行此操作:

  1. Before the form is loaded for all forms by calling jQuery.validator.setDefaults() 在通过调用jQuery.validator.setDefaults()为所有表单加载表单之前
  2. When initializing the form by passing in options on .validate([options]) 通过在.validate([options])入选项来初始化表单时
  3. After initialization by locating the validator object on the form with $("form").data("validator").settings 初始化之后,通过使用$("form").data("validator").settings上的验证器对象

Since you're using MVC, option #2 is out of the question since unobtrusive-validation will automatically initialize the form. 由于您使用的是MVC,选项#2是不可能的,因为不显眼的验证会自动初始化表单。 So let's use option 3 going forward - the goal here is just to be able to customize the settings on the form. 所以让我们继续使用选项3 - 这里的目标只是为了能够自定义表单上的设置。

Override Default Behavior 覆盖默认行为

The default methods we'll want to modify are highlight and unhighlight which will highlight invalid fields or revert changes made by the highlight option, respectively. 我们要修改的默认方法是highlightunhighlight ,它们将分别突出显示无效字段或还原高亮选项所做的更改。 Here's their default behavior 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 );
    }
}

So you have a couple options here as well. 所以你在这里也有几个选择。

  1. Completely replace those functions and write them on your own 完全替换这些功能并自行编写
  2. Wrap those functions and call them like normal but add your own custom code before or after. 包装这些功能并像平常一样调用它们,但在之前或之后添加您自己的自定义代码。

Option 1 - Replace Wholesale 选项1 - 替换批发

This route is pretty easy. 这条路很容易。 Just write whatever you want in there. 只要在那里写下你想要的任何东西。 Maybe seed from the source code, maybe do your own thing. 也许来自源代码的种子,也许做自己的事情。

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

Option 2 - Wrap Functions 选项2 - 包裹功能

This is less intrusive so probably preferable in most cases. 这种侵入性较小,因此在大多数情况下可能更为可取。

Since ultimately you will be replacing the value of valSettings.highlight , you'll need access to a clean pristine version of the original function. 由于最终您将替换valSettings.highlight的值, valSettings.highlight您需要访问原始函数的干净原始版本。 You can save your own or grab one off the global defaults 您可以保存自己的,也可以从全局默认值中删除一个

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

In terms of wrapping JavaScript functions, there are a couple examples here , here , and here ). 在包装的JavaScript函数而言,有几个例子在这里在这里 ,和这里 )。 Here's a parsed down example from one of those, that will help bind this context across function calls, preserve the arity of the arguments being passed, and persist the return value: 以下是其中一个示例的解析示例,它将帮助跨函数调用绑定this上下文,保留传递的参数的arity,并保留返回值:

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

Then you'll also have to quickly define whatever additional behavior you want to fire whenever the call is made. 然后,您还必须快速定义在调用时要触发的任何其他行为。 In this case, let's find the closest parent div to the element and update it's classes like this: 在这种情况下,让我们找到最接近元素的父div并更新它的类,如下所示:

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

Wrapping It All Up (see what I did there) 全部包装 (看看我在那里做了什么)

$(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);
}

So when we combine all of the above functions, it should look something like this: 因此,当我们结合所有上述函数时,它应该看起来像这样:

Working Demo in Stack Snippets and jsFiddle 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM