【问题标题】:Unobtrusive validation in Chrome won't validate with dd/mm/yyyyChrome 中的不显眼验证不会使用 dd/mm/yyyy 进行验证
【发布时间】:2011-10-17 21:58:25
【问题描述】:

我正在尝试在不同浏览器中使用日期选择器来使用最简单的方案。我怀疑我正在以错误的方式做一些非常简单的事情,但是经过大量搜索后,我仍然没有找到解决方案。下面是一些代表我正在尝试的示例代码。

如果我使用 Chrome (v12.0.742.122) 并从选择器中选择一个日期,例如 13/08/2011,即使我已将格式明确指定为 'dd,jQuery 验证逻辑也不允许提交页面/毫米/年'。

如果我将格式更改为“dd/M/yy”并选择像 2011 年 8 月 13 日这样的日期,它可以在 Chrome 中运行,但不会在 IE (v8.0.7600.16385) 中为我提交。在 FireFox (v3.6.18) 中,这两种格式都有效。

我需要什么验证脚本才能在 Chrome 中支持“dd/mm/yy”的日期格式?

<html>
 <head>
  <link rel="stylesheet" type="text/css" href="jquery-ui.css" />
  <script type="text/javascript" src="jquery-1.4.4.js"></script>
  <script type="text/javascript" src="jquery.validate.js"></script>
  <script type="text/javascript" src="jquery.validate.unobtrusive.js"></script>
  <script type="text/javascript" src="jquery-ui.js"></script>
  <script type="text/javascript">
      $(document).ready(function () {
    $('.date').datepicker({ dateFormat: 'dd/mm/yy' });
            $.validator.addMethod("dateRule", function(value, element) {
      return true;
    },
    "Error message");
      });
  </script>
 </head>
 <body>
    <form>
        Date: <input type="text" name="myDate" class="date dateRule" />
        <input type="submit" />
    </form>
 </body>
</html>

【问题讨论】:

    标签: jquery jquery-ui jquery-validate datepicker unobtrusive-validation


    【解决方案1】:

    四个小时后,我终于偶然发现了answer。出于某种原因,Chrome 似乎有一些内在的偏好,即使用美国日期格式,其中 IE 和 FireFox 能够明智地使用操作系统上的区域设置。

    jQuery.validator.methods["date"] = function (value, element) { return true; } 
    

    【讨论】:

    • 我花了大约一个小时才在这里找到答案。这行代码完美运行。
    • 这条线应该放在哪里?
    • @Rusty 你可以把它放在任何地方,在你需要进行日期验证之前执行它。我在 $(document).ready 函数中有它。
    • 这忽略了验证!!你是认真的吗?!
    • IE and FireFox 不要使用 操作系统上的区域设置 - 只是如果您输入 76/85/2015 他们会生成一个日期,即使它不是有效的日期。只有 Chome 将其正确报告为无效日期。这个答案意味着你永远不会得到客户端验证。
    【解决方案2】:

    您可以使用此处提供的 Globalize.js 插件:https://github.com/jquery/globalize

    然后像这样简单地在您网站的主脚本文件中重新定义 validate 方法(避免编辑 jquery.validate.js 库文件,因为您可能希望将来更新它):

    $.validator.methods.date = function (value, element) {
        return this.optional(element) || Globalize.parseDate(value, "d/M/y", "en");
    }
    

    【讨论】:

    • 这应该被认为是答案。 +1
    • 对于寻找这个的其他人......应该有一个大的“M”,即d/M/y作为一个小的符号分钟,它在不应该的时候起作用!
    【解决方案3】:

    我知道我参加聚会有点晚了,但这是我用来验证 Chrome 不接受英国格式日期的解决方案。一个简单的即插即用验证,它不依赖任何插件或修改任何文件。它将接受 1900 年 1 月 1 日至 2999 年 31 月 31 日之间的任何日期,因此采用美国或英国格式。显然有无效的日期会偷偷过去,但您可以根据自己的喜好调整正则表达式。这满足了我的需求,因为它将用于站点的低流量区域,并带有服务器端验证。有问题的站点区域是使用 ASP.net MVC 构建的。

    jQuery.validator.methods.date = function(value, element) {
        var dateRegex = /^(0?[1-9]\/|[12]\d\/|3[01]\/){2}(19|20)\d\d$/;
        return this.optional(element) || dateRegex.test(value);
    };
    

    【讨论】:

    • 我使用了一个比这个更复杂的正则表达式,但比另一个答案中的大规模正则表达式更复杂。它不检查字符串的结尾,以允许时间跟随。 var dateRegex = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|10|11|12)\/(19|20)\ d\d\D/;超出范围的问题由日期或日期时间选择器的约束处理。
    • 实际上,使 var dateRegex = /^(0?[1-9]|[12]\d|3[01])\/(0?[1-9]|10| 11|12)\/(19|20)\d\d(\D.*)?$/;现在它只支持日期的情况下不支持尾随字符(我正在使用日期时间)
    • 感谢大卫 :)。只是为了澄清任何发现这一点的人,前一个接受英国日期,然后是非数字,然后是其他任何内容。底部的将仅接受英国格式的日期。它们为仅限英国格式的日期提供了更好的匹配,尽管仍然会遗漏一些边缘情况(例如 31/02)。
    • 谢谢!太棒了
    • 这是结合客户端和服务器端验证的最佳实用响应。我刚刚花了几个小时与 globalize 和相关的 globalize js 文件搏斗,但没有让它们在所有 IE、Chrome 和 Firefox 中工作并最终退出所有内容。如果我从一开始就使用它,我会花 10 分钟的时间,对用户没有明显的问题。
    【解决方案4】:

    JQuery 团队似乎已经提出了这个问题。

    https://github.com/jzaefferer/jquery-validation/issues/153

    目前看来解决方法是在 additional-methods.js 中使用 dateITA

    看起来像这样:

    jQuery.validator.addMethod(
        "dateITA",
        function(value, element) {
            var check = false;
            var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
            if( re.test(value)){
                var adata = value.split('/');
                var gg = parseInt(adata[0],10);
                var mm = parseInt(adata[1],10);
                var aaaa = parseInt(adata[2],10);
                var xdata = new Date(aaaa,mm-1,gg);
                if ( ( xdata.getFullYear() == aaaa ) 
                       && ( xdata.getMonth () == mm - 1 ) 
                       && ( xdata.getDate() == gg ) )
                    check = true;
                else
                    check = false;
            } else
                check = false;
            return this.optional(element) || check;
        },
        "Please enter a correct date"
    );
    

    如果添加该验证器,则可以将日期选择器附加到“.dateITA”类。

    到目前为止,这对我来说效果很好,让我摆脱了 Chrome 中的这个愚蠢问题。

    【讨论】:

      【解决方案5】:

      这在 .net mvc4 中仍然是一个问题,其中 EditorFor DateTime 仍然会产生 data-val-date 属性,尽管 jQuery 验证插件中有明确的文档不要使用它!!!希望微软能解决这个问题,data-val-date 再也不会听说了!

      与此同时,您可以通过 modernizr 使用建议的库:

      yepnope({
          test: isNaN(Date.parse("23/2/2012")),
          nope: 'http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.min.js',
          complete: function () {
              $.validator.methods.date = $.validator.methods.dateITA
          }
      });
      

      或者如果不想使用 yepnope/modernizr,并摆脱 dateITA 方法的 UTC 组件(如果使用此库输入本地时间,日期将不会总是在该月的第一天或最后一天生效除非在格林威治线上 - 即 UTC +0):

      (function ($) {
          var invokeTestDate = function () {
              return $.validator.methods.date.call({
                  optional: function () {
                      return false;
                  }, (new Date(2012,8,23)).toLocaleDateString(), null);
          };
          if (invokeTestDate()) {
              return;
          }
      
          // http://docs.jquery.com/Plugins/Validation/Methods/date
      
          $.validator.methods.date = function (value, element) {
              //ES - Chrome does not use the locale when new Date objects instantiated:
              //return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
              var d = new Date();
              return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
          }
      })(jQuery);
      

      【讨论】:

        【解决方案6】:

        在调用您的验证文件后,我发现此错误最简单的更正方法是以下代码 sn-p;

            jQuery.validator.methods["date"] = function (value, element){
                var shortDateFormat = "dd/mm/yy";
                var res = true;
                try {
                    $.datepicker.parseDate(shortDateFormat, value);
                } catch (error) {
                    res = false;
                }
                return res;
            }
        

        即使在 2016 年发现的版本中,如果 Chrome 和 Firefox 中没有上述代码,我仍然会遇到这个问题。

        这是我的首选解决方案,因为它不需要任何额外的库或插件即可工作。

        我在谷歌搜索问题here.时发现了这个代码sn-p

        【讨论】:

          【解决方案7】:

          我们使用以下内容来处理我们的项目;

          if ($.validator) {
              $.validator.addMethod("date",
                  function (value, element, params) {
                      if (this.optional(element)) {
                          return true;
                      }
          
                      var ok = true;
                      try {
                          $.datepicker.parseDate("dd/mm/yy", value);
                      }
                      catch (err) {
                          ok = false;
                      }
                      return ok;
                  });
          }
          

          【讨论】:

            【解决方案8】:

            希望这段代码对您有所帮助。

            $.validator.addMethod(
                     "date",
                     function(value, element) {
                          var check = false;
                          var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
                          var reBR = /^\d{4}\-\d{1,2}\-\d{1,2}$/;
                          if( re.test(value)){
                               var adata = value.split('/');
                               var gg = parseInt(adata[0],10);
                               var mm = parseInt(adata[1],10);
                               var aaaa = parseInt(adata[2],10);
                               var xdata = new Date(aaaa,mm-1,gg);
                               if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
                                    check = true;
                               else
                                    check = false;
                          } else if( reBR.test(value)){
                               var adata = value.split('-');
                               var aaaa = parseInt(adata[0],10);
                               var mm = parseInt(adata[1],10);
                               var gg = parseInt(adata[2],10);
                               var xdata = new Date(aaaa,mm-1,gg);
                               if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
                                    check = true;
                               else
                                    check = false;
                          } else
                               check = false;
                               console.log(check);
                          return this.optional(element) || check;
                     },
                     "Por favor insira uma data válida"
                );
            

            【讨论】:

            • 你从哪里得到这个代码?你自己创造的吗?为什么你认为它会起作用?
            【解决方案9】:

            应将您在 validate 中定义的 dateRule 方法更改为(例如,正则表达式只是一个简单的方法):

            $.validator.addMethod(
                "dateRule",
                function(value, element) {
                    return value.match(/^\d\d?\/\d\d?\/\d\d$/);
                },
                "Please enter a date in the format dd/mm/yy"
            );
            

            您可以根据需要切换正则表达式。我从here 得到了这个日期的正则表达式,它支持 M/D/YY 或 M/D/YYYY 或 MM/DD/YYYY 或 MM/DD/YY:1/1/1920 到 12/31/2019; 2 月 29 日和 30 日始终允许

            ^((0?[13578]|10|12)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1}))|(0?[2469]|11)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1})))$
            

            【讨论】:

            • 这将是下一步。目前,我什至无法通过始终返回 true 来让 Chrome 通过验证。
            • 我无法复制您的问题。我似乎可以提交表格。您可以尝试不包括 jquery.validate.unobtrusive.js 并添加 $('form').validate();
            • 排除 jquery.validate.unobtrusive.js 让 Chrome 提交表单。现在我需要了解如何配置不显眼的验证规则来工作。
            • 这可能会有所帮助:click here
            • 这似乎无助于让 Chrome 验证 dd/mm/yyyy,因为它还允许 mm/dd/yyyy
            【解决方案10】:

            我还找到了一个似乎适用于任何文化的解决方案。

            http://devdens.blogspot.com/2011/11/jquery-validation-fix-for-date-format_29.html

            它需要你修改实际的 jquery.valdiation.min.js 文件,但到目前为止它对我有用。

            【讨论】:

            • 答案应该包含更多信息,而不仅仅是一个链接。您应该(至少)将一些内容总结到您的答案中。
            【解决方案11】:

            这是唯一对我有用的解决方案: http://www.codeproject.com/Tips/579279/Fixing-jQuery-non-US-Date-Validation-for-Chrome

             jQuery.extend(jQuery.validator.methods, {
                    date: function (value, element) {
                        var isChrome = window.chrome;
                        // make correction for chrome
                        if (isChrome) {
                            var d = new Date();
                            return this.optional(element) || 
                            !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
                        }
                        // leave default behavior
                        else {
                            return this.optional(element) || 
                            !/Invalid|NaN/.test(new Date(value));
                        }
                    }
                }); 
            

            【讨论】:

              【解决方案12】:

              或者我们可能会尝试覆盖验证器而不是忽略它。

              $.validator.addMethod("date", function (value, element) {
                  var result = true;
                  try {
                      $.datepicker.parseDate('dd/mm/yy', value);
                  }
                  catch (err) {
                      result = false;
                  }
                  return result;
              });
              

              【讨论】:

                猜你喜欢
                • 2013-07-06
                • 2015-10-30
                • 1970-01-01
                • 1970-01-01
                • 2017-04-07
                • 2014-04-18
                • 1970-01-01
                • 2022-11-01
                相关资源
                最近更新 更多