我想使用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。还有什么我可能会失踪吗?
答案 0 :(得分:21)
正如我在评论中提到的,正在发生的事情是datepicker
指令正在将模型值从String
更改为Date
对象。当ngPattern
尝试验证Date
对象时,它将失败,因为Date
的字符串值与您正在使用的模式不匹配。
您可以创建自己的指令,挂钩$parsers of the ngModelController以运行模式检查,然后根据值来调用$setValidity()
。 $parsers
实际上是针对此类功能而构建的,您希望在ngModel
值上运行自己的自定义验证。
遵循这些项目符号是一项指令,可以完成您想要的功能。在向您展示代码之前,我想解释指令中的逻辑:
ngModel
添加一个require,以便您可以访问ngModelController
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。
如果您没有注意到 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;回到有效。