Skip to main content
 首页 » 编程设计

同一表单组的 JQuery 验证和 Bootstrap 3

2026年07月28日5mate10pro

我有一个关于“has-error”类和复杂对象的问题。

基本上对于单个简单类型它工作得很好,但对于复杂对象则不然。

我有以下代码:

我的验证:

public static MvcHtmlString ValidationErrorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string error) 
{ 
    if (HasError(htmlHelper, ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData), ExpressionHelper.GetExpressionText(expression))) 
        return new MvcHtmlString(error); 
    else 
        return null; 
} 
 
 
private static bool HasError(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression) 
{ 
    string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression); 
    FormContext formContext = htmlHelper.ViewContext.FormContext; 
    if (formContext == null) 
        return false; 
 
    if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName)) 
        return false; 
 
    ModelState modelState = htmlHelper.ViewData.ModelState[modelName]; 
    if (modelState == null) 
        return false; 
 
    ModelErrorCollection modelErrors = modelState.Errors; 
    if (modelErrors == null) 
        return false; 
 
    return (modelErrors.Count > 0); 
} 

Javascript

$.validator.setDefaults({ 
    highlight: function (element) { 
        $(element).closest(".form-group").addClass("has-error"); 
    }, 
    unhighlight: function (element) { 
        $(element).closest(".form-group").removeClass("has-error"); 
    } 
}); 

这是我的编辑器模板:

@model DatingWebsite.Models.UserDate 
 
<div class="form-group@(Html.ValidationErrorFor(m=>m, " has-error"))"> 
    @Html.LabelFor(m=>m.Birthdate, new {@class="col-sm-2 control-label"}) 
    <div class="col-sm-10"> 
        @Html.DropDownListFor(model => model.Day, Enumerable.Range(1, 31).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString() }), Base.Day, new {@class="form-control" }) 
        @Html.DropDownListFor( model => model.Month, Enumerable.Range(1, 12).Select(i => new SelectListItem { Value = i.ToString(), Text = System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i)}), Base.Month, new {@class="form-control" }) 
        @Html.DropDownListFor( model => model.Year,  Enumerable.Range(DateTime.Now.AddYears(-80).Year, 80-18).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString()}), Base.Year, new {@class="form-control" }) 
 
        @Html.ValidationMessageFor(m => m.Day, null, new { @class = "help-block" }) 
        @Html.ValidationMessageFor(m => m.Month, null, new { @class = "help-block" }) 
        @Html.ValidationMessageFor(m => m.Year, null, new { @class = "help-block" }) 
    </div> 
</div> 

这是模型:

[Required] 
public int Day { get; set; } 
[Required] 
public int Month { get; set; } 
[Required] 
public int Year { get; set; } 

现在你可以看到我所做的验证(m=>m),所以我传递了整个对象。

1)如果我没有填写任何内容并提交,我会将所有内容变为红色,因此应用了样式,并且我收到了所有红色错误消息。

2)我将第一个下拉列表更改为一个值,然后颜色消失,并且不再是红色,尽管我仍然看到其他 2 个错误消息...

3)如果我再次这样提交,它就不会再变成红色了。

注意:我添加的图片不是下拉列表,而是文本框,因为它也有同样的问题。

有人知道代码出了什么问题吗?

更新

我注意到,当我向一个文本框添加值时,JavaScript 会调用 unheighlight 函数并删除 has-error 类,并且不会为其他 2 个文本框调用突出显示函数。

请您参考如下方法:

我刚刚遇到了同样的问题并找到了解决方案。虽然不太漂亮,但似乎可行。

我已将类 multi-validation-group 添加到我的 form-group div 中,该 div 可以包含多个错误消息,然后实现以下自定义取消突出显示功能,该函数仅当没有错误标签可见时,才会从 form-group div 中删除 has-error 类。

jQuery.validator.setDefaults({ 
  errorClass: "has-error", 
  highlight: function(element, errorClass, validClass) { 
    $(element).closest(".form-group").addClass(errorClass); 
  }, 
  unhighlight: function(element, errorClass, validClass) { 
    var group = $(element).closest(".form-group"); 
    var removeClass = true; 
 
    if (group.hasClass("multi-validation-group")) { 
      removeClass = $(group).find("label.has-error:not(:hidden)").length == 0; 
    } 
 
    if (removeClass) { 
      group.removeClass(errorClass); 
    } 
  } 
});