Achyut
Achyut

Reputation: 808

Angular making input field null on validation failure

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

Answers (2)

Sai
Sai

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

Bertrand
Bertrand

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

Related Questions