@@ -1454,9 +1454,8 @@ For more info on the topic, you can take a look at this
14541454
14551455## Migrating from 1.3 to 1.4
14561456
1457- Angular 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
1458- are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions `and some fixes to core filters:
1459- `limitTo` and `filter`.
1457+ AngularJS 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
1458+ are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions`, `ngPattern`, `pattern` and some fixes to core filters: `limitTo` and `filter`.
14601459
14611460The reason for the ngAnimate refactor was to fix timing issues and to expose new APIs to allow
14621461for developers to construct more versatile animations. We now have access to `$animateCss`
@@ -1469,9 +1468,9 @@ to render error messages with ngMessages that are listed with a directive such a
14691468involves pulling error message data from a server and then displaying that data via the mechanics of ngMessages. Be
14701469sure to read the breaking change involved with `ngMessagesInclude` to upgrade your template code.
14711470
1472- Other changes, such as the ordering of elements with ngRepeat and ngOptions, may also affect the behavior of your
1473- application. And be sure to also read up on the changes to `$cookies`. The migration jump from 1.3 to 1.4 should be
1474- relatively straightforward otherwise.
1471+ Other changes, such as the ordering of elements with ngRepeat and ngOptions and the way ngPattern and pattern directives
1472+ validate the regex, may also affect the behavior of your application. And be sure to also read up on the changes to `$cookies`.
1473+ The migration jump from 1.3 to 1.4 should be relatively straightforward otherwise.
14751474
14761475
14771476
@@ -1575,7 +1574,7 @@ class based animations (animations triggered via ngClass) in order to ensure tha
15751574
15761575
15771576
1578- ### Forms (`ngMessages`, `ngOptions`, `select`)
1577+ ### Forms (`ngMessages`, `ngOptions`, `select`, `ngPattern` and `pattern` )
15791578
15801579#### ngMessages
15811580The ngMessages module has also been subject to an internal refactor to allow it to be more flexible
@@ -1683,6 +1682,79 @@ ngModelCtrl.$formatters.push(function(value) {
16831682});
16841683```
16851684
1685+ #### ngPattern and pattern
1686+
1687+ Due to [0e001084](https://github.com/angular/angular.js/commit/0e001084ffff8674efad289d37cb16cc4e46b50a),
1688+ The `ngPattern` and `pattern` directives will validate the regex
1689+ against the `$viewValue` of `ngModel`, i.e. the value of the model
1690+ before the $parsers are applied. Previously, the `$modelValue`
1691+ (the result of the $parsers) was validated.
1692+
1693+ This fixes issues where `input[date]` and `input[number]` cannot
1694+ be validated because the `$viewValue` string is parsed into
1695+ `Date` and `Number` respectively (starting with Angular 1.3).
1696+ It also brings the directives in line with HTML5 constraint
1697+ validation, which validates against the input value.
1698+
1699+ This change is unlikely to cause applications to fail, because even
1700+ in Angular 1.2, the value that was validated by pattern could have
1701+ been manipulated by the $parsers, as all validation was done
1702+ inside this pipeline.
1703+
1704+ If you rely on the pattern being validated against the `$modelValue`,
1705+ you must create your own validator directive that overwrites
1706+ the built-in pattern validator:
1707+
1708+ ```
1709+ .directive('patternModelOverwrite', function patternModelOverwriteDirective() {
1710+ return {
1711+ restrict: 'A',
1712+ require: '?ngModel',
1713+ priority: 1,
1714+ compile: function() {
1715+ var regexp, patternExp;
1716+
1717+ return {
1718+ pre: function(scope, elm, attr, ctrl) {
1719+ if (!ctrl) return;
1720+
1721+ attr.$observe('pattern', function(regex) {
1722+ /**
1723+ * The built-in directive will call our overwritten validator
1724+ * (see below). We just need to update the regex.
1725+ * The preLink fn guaranetees our observer is called first.
1726+ */
1727+ if (isString(regex) && regex.length > 0) {
1728+ regex = new RegExp('^' + regex + '$');
1729+ }
1730+
1731+ if (regex && !regex.test) {
1732+ //The built-in validator will throw at this point
1733+ return;
1734+ }
1735+
1736+ regexp = regex || undefined;
1737+ });
1738+
1739+ },
1740+ post: function(scope, elm, attr, ctrl) {
1741+ if (!ctrl) return;
1742+
1743+ regexp, patternExp = attr.ngPattern || attr.pattern;
1744+
1745+ //The postLink fn guarantees we overwrite the built-in pattern validator
1746+ ctrl.$validators.pattern = function(value) {
1747+ return ctrl.$isEmpty(value) ||
1748+ isUndefined(regexp) ||
1749+ regexp.test(value);
1750+ };
1751+ }
1752+ };
1753+ }
1754+ };
1755+ });
1756+ ```
1757+
16861758
16871759### form
16881760
0 commit comments