【问题标题】:jQuery Validate: add error or validate class to parent divjQuery Validate:向父 div 添加错误或验证类
【发布时间】:2025-12-23 23:00:12
【问题描述】:

我正在使用 Twitter 的 Bootstrap 作为我正在从事的项目的框架。我正在尝试使用 jQuery Validate 插件来验证一个简单的联系表单,但这会引起一些麻烦。

我希望将 ErrorValid 类添加到每个表单输入的 父 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。我曾尝试使用 highlight(建议 here,但这根本不起作用)和 errorPlacement(见下文)但我没有正确执行.

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

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

谁能建议我应该使用什么选项来实现这一目标?!

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

【问题讨论】:

  • 它看起来应该是 $(error).parent('div').addClass('error'); 让我知道它是否成功
  • @gdoron 感谢您的建议,遗憾的是它没有奏效。我在上面发布的代码导致应用类,但有两个错误:1.)当字段有效时它不会删除类 2.)它只对错误起作用(理想情况下我想添加一个有效输入的替代类)

标签: jquery validation jquery-validate twitter-bootstrap


【解决方案1】:

尝试使用highlightunhighlight 函数:

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

【讨论】:

  • 感谢您的建议。事实上,我已经尝试过这种方法。我已经按照建议插入了代码并且没有任何功能......表单验证甚至没有触发!我已经仔细检查了 Firebug,没有出现任何错误。如果有帮助的话,我正在使用插件的 v1.9.0 和 jQuery 的 v1.7.1。
  • 我认为您的&lt;button type="submit"&gt; 可能需要成为&lt;input type="submit"&gt; 才能触发验证?不确定表单的提交事件是否由&lt;button&gt; 触发?
  • 没想到!唉,还是不开心!!元素类型似乎没有什么不同。想一想,如果这就是问题的原因,那连基本的验证都不会触发吗?! Annnnnyyyywwaaaayy ......这是一个奇怪的。我想不出任何(明显的)为什么这不起作用的原因。
  • 出于兴趣,您使用的是 IE 吗?过去,我已经将占位符作为值进行验证,因此不会触发“必需”验证器。
  • 不,我使用 Firefox 作为我正在构建项目的主要浏览器。之后我将进行跨浏览器测试....我尝试删除占位符引用,但这仍然没有'不提交(使用高亮方法)。
【解决方案2】:

来自我对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 - 这里的目标只是能够自定义表单上的设置。

覆盖默认行为

我们要修改的默认方法是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. 包装这些函数并像往常一样调用它们,但在之前或之后添加您自己的自定义代码。

选项 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 上下文,保留传递的参数的数量,并保留返回值:

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>

【讨论】:

    【解决方案3】:

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

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

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

    希望对你有帮助

    【讨论】: