ng-pattern不使用angular ui datepicker

时间:2014-05-20 15:33:05

标签: angularjs angular-ui

我想使用ng-pattern使用Angular UI datepicker在输入字段上进一步强制执行日期格式。问题是,当我这样做时,它始终显示无效。

<p class="input-group">
    <input type="text" datepicker-popup="MM/dd/yyyy" is-open="opened" close-text="Close"
        ng-model="someDate" class="form-control" placeholder="mm/dd/yyyy"
        ng-pattern="/^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/" required />
    <span class="input-group-btn">
        <button type="button" class="btn btn-default" ng-click="open($event)">
            <i class="glyphicon glyphicon-calendar"></i>
        </button>
    </span>
</p>

如果我将相同的ng-pattern应用于普通输入字段(无日期选择器),它将按预期工作。

似乎存在冲突,但我不确定它是什么。有什么想法吗?

更新

Here是一个简单的插件,可根据要求说明问题。经过一些进一步的挖掘后,它似乎正在针对底层Date对象运行模式。但是,当我使用格式化日期的自定义指令时,它会根据实际输入运行它。

我在ng-pattern中看到的唯一文档是在输入下简要提及here。还有什么我可能会失踪吗?

3 个答案:

答案 0 :(得分:21)

正如我在评论中提到的,正在发生的事情是datepicker指令正在将模型值从String更改为Date对象。当ngPattern尝试验证Date对象时,它将失败,因为Date的字符串值与您正在使用的模式不匹配。

您可以创建自己的指令,挂钩$parsers of the ngModelController以运行模式检查,然后根据值来调用$setValidity()$parsers实际上是针对此类功能而构建的,您希望在ngModel值上运行自己的自定义验证。

遵循这些项目符号是一项指令,可以完成您想要的功能。在向您展示代码之前,我想解释指令中的逻辑:

  • 要添加自己的$解析器,您必须在指令定义中为ngModel添加一个require,以便您可以访问ngModelController
  • 因为RegExp期望模式参数没有开始和尾部斜杠,所以我在模式指令参数中删除了它们
  • datepicker将模型值从String更改为Date。由于datepicker使用unshift将$解析器函数添加到$parsers数组的开头,因此我们还需要使用unshift将$解析器放在{{1}之前}'$ parser。
  • 正如您所提到的,datepicker指令将采用可以解析为日期的任何值并将其用于模型。为了确保只使用与模式匹配的日期,我将返回datepicker(在文档中指定),以查找与模式不匹配的日期。我没有对作为undefined对象的值进行此检查,因为这意味着它是使用Date小部件选择的。
  • 正如我在前一篇文章中提到的,如果该值已经是datepicker对象,我就不会进行有效性检查,因为这意味着它是使用Date小部件选择的意味着它是一个有效的日期。

指令代码

datepicker

html - 确保您不要忘记删除正则表达式定义中的开头和尾部斜杠:

app.directive('awDatepickerPattern',function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope,elem,attrs,ngModelCtrl) {
      var dRegex = new RegExp(attrs.awDatepickerPattern);

      ngModelCtrl.$parsers.unshift(function(value) {

        if (typeof value === 'string') {
          var isValid = dRegex.test(value);
          ngModelCtrl.$setValidity('date',isValid);
          if (!isValid) {
            return undefined;
          }
        }

        return value;
      });

    }
  };
});

以下是我的代码更新plunker

那又为什么没有ng-pattern工作?

如果您没有注意到 root 导致ng-pattern与aw-datepicker-pattern="^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$" 指令一起使用时无效的原因是因为datepicker指令添加了它使用datepicker将ngModelController $ parser拥有到$ parsers数组的开头,这会将模型值从unshift更改为String

答案 1 :(得分:4)

此处发布的其他解决方法似乎是升级到 AngularJS 1.4.5 ,2015-08-28发布:

https://github.com/angular/angular.js/blob/master/CHANGELOG.md#145-permanent-internship-2015-08-28

答案 2 :(得分:3)

上述指令plunker仅在需要日期时才有效。我通过修改指令来修复它,如下所示:

ngModelCtrl.$setValidity('datep',isValid);

由于日期选择器在此指令之后运行,因此它设置了&#39; date&#39;回到有效。

相关问题