7

我正在使用 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,但这根本不起作用)和errorPlacement(见下文),但我没有正确地做到这一点。

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

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

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

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

4

3 回答 3

13

尝试使用highlightandunhighlight函数:

$("#msg-form").validate({
    highlight: function(element) {
        $(element).parent('div').addClass('error');
    },
    unhighlight: function(element) {
        $(element).parent('div').removeClass('error');
    }
});
于 2012-05-03T13:10:41.297 回答
4

如果使用 jquery 验证发生验证错误,则从我对将类添加到父 div 的回答中,因为我相信它为这个问题的现有答案增加了价值......

访问验证器设置

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

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

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

覆盖默认行为

我们要修改的默认方法是highlight并且unhighlight将分别突出显示无效字段或恢复由突出显示选项所做的更改。根据源代码,这是它们的默认行为:

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>

于 2017-07-28T18:41:17.323 回答
0

我可能错了,但看起来您需要 .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);
},

希望这可以帮助

于 2013-02-20T21:10:46.473 回答