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

Posted

技术标签:

【中文标题】jQuery-validate 自定义规则导致其他无效字段被忽略【英文标题】:jQuery-validate custom rules cause other invalid fields to be ignored 【发布时间】:2017-09-02 21:39:29 【问题描述】:

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

我正在使用 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 库和 microsoft jquery-validate-unobtrusive.js所以这些似乎工作正常。

我的部分问题是日期和时间选择器(注意 UIHint 属性),它使用自定义编辑器模板,该模板基本上创建了 DevExpress 日期时间选择器(为了方便以后我添加了两个类,具体取决于选择器是否用于日期或时间输入(devexpress-date devexpress-time)。这可以正常工作,并且所需的验证属性等都可以通过。但是......由于它们被认为是日期和时间输入,因此它们基于格式(以日期为例,它只接受格式 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

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

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

谢谢。

【问题讨论】:

【参考方案1】:

我在 1.14 版本中遇到了这个问题。升级 jquery.validate.js 到 1.17 和 jquery.validate.unobtrusive.js 到 3.2.6 解决了这个问题。

【讨论】:

以上是关于jQuery-validate 自定义规则导致其他无效字段被忽略的主要内容,如果未能解决你的问题,请参考以下文章

jquery-validator 的使用方法

jquery-validation 使用

验证插件(jquery-validate)

jQuery-validate插件初级篇

为啥动画自定义 CALayer 属性会导致其他属性在动画期间为零?

如何使唯一数组的自定义验证规则依赖于其他字段 laravel