Reputation: 808
I am creating a member registration form where he enters his membership card number. The membership card number is a 19 digit number which starts with 6 4's and then followed by 13 digits.Now the user has the option to enter either last 13 digits alone or he can even enter the complete 19 digits. When he enters complete 19 digits on the blur event i trim the 1st 6 digits which leaves the last 13 digits. My code works fine for all scenarios but something weird happens when error happens in 1 particular scenario.
Working Scenarios are
Failed Scenario
Please find the code below-
HTML
<input type="text" ng-model="user.CardNumber" ng-blur="trimCardNumber()" ng-required="true" ng-pattern="/^[0-9]{13,19}$/" name="CardNumber">
Controller.JS
$scope.trimCardNumber = function () {
if (($scope.user.CardNumber).indexOf("444444") > -1) {
$scope.user.CardNumber = ($scope.user.CardNumber).replace("444444", "");
$scope._ServerForm.CardNumber.$invalid = false;
return true;
}
else if ($scope.user.CardNumber.length != 13) {
$scope._ServerForm.CardNumber.$invalid = true;
}
else {
$scope._ServerForm.CardNumber.$invalid = false;
}
}
I have created a JS fiddle for the issue - http://jsfiddle.net/achyut/x69hZ/1/
Steps to reproduce -
Upvotes: 4
Views: 3442
Reputation: 2068
The issue is discussed in the following thread
input not showing invalid model values
You can create your custom directive and validate it accordingly.
Upvotes: 3
Reputation: 13570
This is happening because of the way the digest cycle works.
When blur occurs trimCardNumber() removes the six 4's from the input.
$scope.user.CardNumber = $scope.user.CardNumber.replace("444444", "");
Because something changed during the digest cycle it becomes dirty and so a second round is triggered. In the second round the input now has less digits and this is causing the regex to invalidate it and clean the user.CardNumber model.
For example this card number (with 19 digits) will fail: 4444441111111111111 because after removing the 4's it will be invalidated by the regex.
if you change the regex to accept 12 to 19 the number above will work but a 18 numbers long would also fail.
Here is a fiddle
I think the solution is to move the regex inside trimCardNumber(), or even better, you could create a custom validation for the input.
Upvotes: 1