jQuery-验证自定义规则导致其他无效字段被忽略

jQuery-validate custom rules cause other invalid fields to be ignored

抱歉,这可能真的很愚蠢,但我无法解决这个问题。

我正在使用 C#,ASP.NET MVC 5 并且在我的模型中有以下内容:

    /// <summary>
    /// A none-nullable datetime representing the start of the meeting.
    /// </summary>
    [Display(Name = "Date")]
    [UIHint("Date")]
    public System.DateTime Start { get; set; }

    /// <summary>
    /// The time aspect of the Meeting Start is split off from the date
    /// portion. This property allows us to correctly display a separate
    /// date and time but uses the same underlying property.
    /// </summary>
    [Display(Name = "Time")]
    [UIHint("Time")]
    public System.DateTime StartTime
    {
        get
        {
            return Start;
        }
        set
        {
            Start = System.DateTime.ParseExact(Start.ToString("dd/MM/yyyy ") + value.ToString("HH:mm"), "dd/MM/yyyy HH:mm", System.Globalization.CultureInfo.InvariantCulture);

        }
    }

    /// <summary>
    /// The end time of the meeting.
    /// Since the system does not allow meetings to span multiple days this
    /// will be married up with the date part of Start when we save.
    /// </summary>
    [Display(Name = "Planned finish")]
    [UIHint("Time")]
    public System.DateTime Finish { get; set; }

    /// <summary>
    /// Set after the meeting to display actual start time.
    /// </summary>
    [Display(Name = "Started")]
    [UIHint("Time")]
    public System.DateTime Started { get; set; }

    /// <summary>
    /// Set after the meeting to display actual finished time.
    /// </summary>
    [Display(Name = "Finished")]
    [UIHint("Time")]
    public System.DateTime Finished { get; set; }

    [Required]
    [Display(Name ="Primary contact")]
    public string Contact { get; set; }

    [Required]
    [Display(Name = "Secondary contact")]
    public string Contact2 { get; set; }

在浏览器中,这对两个联系人都适用(即表单不会提交,除非他们都有值。)我包括了 jquery-validate.js 库和微软 jquery-validate-unobtrusive.js 所以这些似乎工作正常。

我的部分问题是日期和时间选择器(注意 UIHint 属性),它使用自定义编辑器模板,基本上创建了一个 DevExpress 日期时间选择器(为了方便,稍后我添加了两个 类 取决于选择器是用于日期还是时间输入(devexpress-date devexpress-time)。这工作正常,并且所需的验证属性(例如 required 等)通过得很好。但是......因为它们被认为是日期和时间输入,所以它们失败了基于格式的验证(以日期为例,它只接受格式 yyyy-MM-dd。现在我已经按照此处的示例解决了这个问题:Custom date format with jQuery validation plugin。并且多次制作了类似的。

我将所有这些都放在一个单独的 js 文件中,我在两个验证库(使用捆绑包)之后直接包含在内。这一切在概念上似乎都没有问题(我从 http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2 获得了这个指导)。但是......这里是事情变得有点棘手的地方。

为了澄清,我的 CustomValidators.js 包含:

(function ($) {
$.validator.addMethod("date", function (value, element, params) {
    if (!this.optional(element)) {
        var bits = value.match(/([0-9]+)/gi), str;
        if (!bits)
            return this.optional(element) || false;
        str = bits[1] + '/' + bits[0] + '/' + bits[2];
        alert("testing date " + value);
        return this.optional(element) || !/Invalid|NaN/.test(new Date(str));
    }
    return true;
});
$.validator.unobtrusive.adapters.addBool("date");

$.validator.addMethod('time', function (value, element) {
    value = value.trim();
    alert("Testing time: " + value);
    if (value.length != 5 || value.indexOf(":") == -1) {
        return false;
    }
    var parts = value.split(":");
    var hour = ParseInt(parts[0]);
    var minutes = ParseInt(parts[1]);
    if (isNaN(hour) || isNaN(minutes)) {
        return false;
    }
    if (hour < 0 || hour > 23) {
        return false;
    }
    if (minutes < 0 || minutes > 59) {
        return false;
    }
    return this.optional(element) || true;
});

$.validator.unobtrusive.adapters.addBool("time");

}(jQuery));

** 问题**

因为 devexpress 输入注册为日期时间,所以它尝试使用标准日期时间规则进行验证(返回 false 并给我一个关于无效日期的可爱的验证摘要警告)。

为了解决这个问题,我尝试在 $(document).ready() 上将任何输入与 devexpress-date 和 devexpress-time 属性绑定以具有不同的规则:

        $(document).ready(function () {
        if ($("form").length > 0)
        {
            $("form").each(function () {
                $(this).validate();
                $(".devexpress-date input").each(function () {
                    $(this).addClass("devexpress-date");
                    $(this).rules("add", "date");
                });
            });

            $("form").each(function () {
                $(this).validate();
                $(".devexpress-time input").each(function () {
                    $(this).addClass("devexpress-time");
                    $(this).rules("add", "time");
                    $(this).rules("remove", "date");
                });
            });
          }
        }

您会在我的验证器函数中注意到一些警报,因此当我尝试提交表单时,我得到:

试用日期:08/04/2017
尝试时间:00:00

我没有收到页面上其他三个时间框的提醒,即使 Contact 或 Contact2 字段为空,表单也可以正常提交。就好像我在这些元素之后破坏了验证,但我不明白为什么。

有人能给我解释一下为什么吗?该应用程序将有数字、文本、日期和时间输入,所有这些输入都具有相似的规则,因此理想的解决方案是使自定义规则起作用,以便我可以 运行 上述规则在 document.ready() 中添加任何具有表单并使其基本上自动工作的页面。我以为我已经接近了,但事实上其他验证现在不起作用让我觉得我离我的意图还有很长的路要走,所以感谢所有帮助。

谢谢。

我 运行 加入了 1.14 版。将 jquery.validate.js 升级到 1.17 并将 jquery.validate.unobtrusive.js 升级到 3.2.6 解决了这个问题。