I am trying to write a custom AngularJS directive similar to ngPattern, except that this directive would fail validation if a RegExp does not match.
Following the source of the ngPattern directive, I came up with:
.directive("notPattern", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, elem, attr, ctrl) {
if (!ctrl) return;
var regExp, notPatternExp = attr.notPattern;
attr.$observe("notPattern", function (regex) {
if (angular.isString(regex) && regex.length > 0) {
regex = new RegExp("^" + regex + "$");
}
if (regex && !regex.test) {
var elemClone = angular.element(elem).clone();
var elemHtml = angular.element("<div>").append(elemClone).html();
throw new Error("Expected " + notPatternExp + " to be a RegExp but was " + regex + ". Element: " + elemHtml);
}
regExp = regex || undefined;
ctrl.$validate();
});
ctrl.$validators.notpattern = function (value) {
return ctrl.$isEmpty(value) || angular.isUndefined(regExp) || !regExp.test(value);
};
}
};
})
This works when I specify the regular expression source within the attribute, but I want to allow a RegExp
object to be used directly, like ngPattern.
The problem is that the expression is not being evaluated.
Here is an example JSFiddle:
http://jsfiddle.net/8Lk3pqep/1/
In this example, entering anything other than "abc" into the text field will show "Invalid per 'pattern'!". I expected to see "Invalid per 'notpattern'!" when "abc" is entered, but this appears only when I enter "testRegExp", thus indicating that the attribute value is not being evaluated.
What am I doing wrong?
I know that notPattern can be accomplished with ngPattern via something like:
$scope.testRegExp = {
test: function (value) {
return !/^abc$/.test(value);
}
};
.. but I would like to know why the custom directive is not evaluating the expression.