自定义 jQuery.validate 验证规则导致目标后的 <input> 在 Internet Explorer 上成为必需项

Custom jQuery.validate validation rule causing the <input> after the target to become required on Internet Explorer

我在 ASP.NET MVC 应用程序视图中有一个长表单,其中一个特定输入 "PaxCount" 需要等于其他 2 个字段的总和:AdultCount 和 ChildCount(我不想要出于其他原因自动确定此字段的值)。

<div class="form-group">
    @Html.LabelFor(model => model.PaxCount, htmlAttributes: new { style = "text-align:left ", @class = "control-label col-md-2" })
    <div class="col-md-2 input-group">
        @Html.EditorFor(model => model.PaxCount, new { htmlAttributes = new { placeholder = "0", style = "width:70px;", @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.PaxCount, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.AdultCount, htmlAttributes: new { style = "text-align:left", @class = "control-label col-md-2" })
    <div class="col-md-2 input-group">
        @Html.EditorFor(model => model.AdultCount, new { htmlAttributes = new { placeholder = "0", style = "width:70px;", @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.AdultCount, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    @Html.LabelFor(model => model.ChildCount, htmlAttributes: new { style = "text-align:left", @class = "control-label col-md-2" })
    <div class="col-md-2 input-group">
        @Html.EditorFor(model => model.ChildCount, new { htmlAttributes = new { placeholder = "0", style = "width:70px;", @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.ChildCount, "", new { @class = "text-danger" })
    </div>
</div>

这里是 jQuery 代码,用于向 PaxCount 输入添加新的客户端验证规则:

$.validator.addMethod("checkPaxCount",
    function (value, element, params) {
        $.validator.messages.checkPaxCount = jQuery.validator.format("Passenger count must be the sum of the no. of adults and children.");
        var chCount = parseInt($('#ChildCount').val());
        var adCount = parseInt($('#AdultCount').val());
        return parseInt(value) == chCount + adCount;
    },
    $.validator.messages.checkPaxCount
);

$(document).ready(function () {
    $('#PaxCount').rules('add',
        {
            checkPaxCount: true,
            messages: {
                checkpaxCount: "Error: ChildCount + AdultCount must = PaxCount"
            }
});

这在 Chrome 中完美运行,但是当我在 IE11 中尝试时,出于某种原因,PaxCount 字段成为必填字段。为了解决这个问题,我将 required: false, 添加到我函数的规则列表中,并且它已修复。但是,一旦我这样做了,下面的 AdultCount 字段就变成了必需的。所以我也为这个输入添加了一个新规则:

$('#AdultCount').rules('add',
{
    required: false,
});

同样的事情再次发生,that 下方的 ChildCount 字段成为必填项。依此类推,效果会贯穿整个表格。可以通过在每个字段中添加规则来解决,但我只是想知道为什么会这样,是否有更优雅的解决方案?

为了以防万一,这里是表单使用的模型中相关字段的代码(利用 DataAnnotations):

    [Display(Name = "No. of Passengers")]
    [Range(1,20, ErrorMessage = "Must be between 1 and 20.")]
    public int PaxCount { get; set; }

    [Display(Name = "No. of Adults")]
    [Range(1, 20, ErrorMessage = "Must be between 1 and 20.")]
    public int AdultCount { get; set; }

    [Display(Name = "No. of Children")]
    [Range(0, 20, ErrorMessage = "Must be between 0 and 20.")]
    public int ChildCount { get; set; }

这是因为您的自定义规则不允许该字段为空。

为了在 "optional" 字段上有自定义规则,您需要包含 "OR" this.optional(element)

修改如下...

$.validator.addMethod("checkPaxCount",
    function (value, element, params) {
        $.validator.messages.checkPaxCount = jQuery.validator.format("Passenger count must be the sum of the no. of adults and children.");
        var chCount = parseInt($('#ChildCount').val());
        var adCount = parseInt($('#AdultCount').val());
        return this.optional(element) || (parseInt(value) == chCount + adCount);
    },
    $.validator.messages.checkPaxCount
);