Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
35
rated 0 times [  37] [ 2]  / answers: 1 / hits: 8538  / 10 Years ago, wed, march 19, 2014, 12:00:00

I have a simple html form containing regular text input. ng-minlength, ng-maxlength and ng-pattern angular built-in form input directives are set on the input.



Problem: ng-pattern check is applied before the length check by ng-minlength and ng-maxlength.



Question: how can I change the default check order: i.e. first check for the length, then apply pattern check?



Example:



<body ng-app>

<div>
<form name=myForm>
Name: <input name=name type=text ng-model=name ng-minlength=3 ng-maxlength=16 ng-pattern=/^w+$//>
<div ng-show=myForm.name.$dirty && myForm.name.$invalid>
<span ng-show=myForm.name.$error.pattern>Pattern error</span>
<span ng-show=myForm.name.$error.minlength || myForm.name.$error.maxlength>Length error</span>
</div>
<br/>
<input type=submit value=Submit>
</form>
</div>

</body>


Current behavior:




  • enter # - see Pattern error

  • enter ### - see Pattern error



Desired behavior:




  • enter # - see Length error

  • enter ### - see Pattern error



FYI, related jsfiddle.



Thanks in advance.


More From » angularjs

 Answers
6

Write your own directive:



var mod = angular.module(myApp, []);

mod.directive(nameValidation, function () {
return {
restrict: A,
require: ngModel,
link: function (scope, element, attrs, ngModelCtrl) {
var validate = function (value) {
var minLen = parseInt(attrs.myMinlength, 10),
maxLen = parseInt(attrs.myMaxlength, 10),
pattern = attrs.myPattern,
match = pattern.match(/^/(.*)/([gim]*)$/),
lenErr = false;

if (match) {
pattern = new RegExp(match[1], match[2]);
}
if (!ngModelCtrl.$isEmpty(value)) {
ngModelCtrl.$setValidity(pattern, true);
if ((minLen && value.length < minLen) || (maxLen && value.length > maxLen)) {
ngModelCtrl.$setValidity(length, false);
lenErr = true;
}
else {
ngModelCtrl.$setValidity(length, true);
lenErr = false;
}

if (!lenErr) {
if (match && !pattern.test(value)) {
ngModelCtrl.$setValidity(pattern, false);
}
else {
ngModelCtrl.$setValidity(pattern, true);
}
}
}
else {
ngModelCtrl.$setValidity(length, true);
ngModelCtrl.$setValidity(pattern, true);
}
}

ngModelCtrl.$parsers.push(validate);
ngModelCtrl.$formatters.push(validate);
}
}
});


Then in your HTML, include the app and use the directive:



<body ng-app=myApp>

<div>
<form name=myForm>
Name: <input name=name type=text ng-model=name name-validation= my-minlength=3 my-maxlength=16 my-pattern=/^w+$//>
<div ng-show=myForm.name.$dirty && myForm.name.$invalid>
<span ng-show=myForm.name.$error.pattern>Pattern error</span>
<span ng-show=myForm.name.$error.length>Length error</span>
</div>
<br/>
<input type=submit value=Submit>
</form>
</div>
</body>


The directive uses my-minlength, my-maxlength, and my-pattern for the three values. If length fails, that will trip first. If not, then pattern will show as error if it doesn't match. Consider renaming this directive if you want to use it other places besides name as minlength, maxlength, and pattern can be passed to it via attributes. If they are left off, they will be ignored.



See jsfiddle: http://jsfiddle.net/4zpxk/6/


[#46711] Tuesday, March 18, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
alorac

Total Points: 262
Total Questions: 82
Total Answers: 97

Location: Libya
Member since Mon, Dec 7, 2020
4 Years ago
alorac questions
Sat, Oct 10, 20, 00:00, 4 Years ago
Tue, Sep 22, 20, 00:00, 4 Years ago
Wed, Jul 1, 20, 00:00, 4 Years ago
Wed, Jun 3, 20, 00:00, 4 Years ago
Sun, May 17, 20, 00:00, 4 Years ago
;