Nick
Nick

Reputation: 14273

angularjs - ngMessages and validation not working as expected

I'm adding validation to the user registration page in my app and I'm trying to use ngMessages and the build-in angularjs validation.

I'm experiencing strange behaviour for password matching and with patterns in general.

Here's the code for password matching:

<span>Password (6 to 16 character)</span>
          <span class="item item-input">
                    <input type="password"
                           ng-model="userRegistration.password"
                           placeholder="password"
                           name="password"
                           ng-minlength="6"
                           ng-maxlength="16"
                           required
                           ng-class="{'invalid-input': userRegistrationForm.password.$touched && userRegistrationForm.password.$invalid }">
                </span>
          <!-- Form validation messages -->
          <div role="alert" class="error-message" ng-messages="userRegistrationForm.password.$error" ng-show="userRegistrationForm.password.$touched">
            <p ng-message="required">This field is required</p>
            <p ng-message="minlength">This field is too short</p>
            <p ng-message="maxlength">This field is too long</p>
          </div>
          <span>Confirm Password</span>
          <span class="item item-input">
                    <input type="password"
                           placeholder="confirm password"
                           ng-model="userRegistration.passwordConfirmation"
                           name="confpass"
                           ng-minlength="6"
                           ng-maxlength="16"
                           ng-pattern="/^{{userRegistration.password}}$/"
                           required
                           ng-class="{'invalid-input': userRegistrationForm.confpass.$touched && userRegistrationForm.confpass.$invalid }">
                </span>
          <!-- Form validation messages -->
          <div role="alert" class="error-message" ng-messages="userRegistrationForm.confpass.$error" ng-show="userRegistrationForm.confpass.$touched">
            <p ng-message="required">This field is required</p>
            <p ng-message="pattern">Password not matching!</p>
          </div>

The problem is that even If the password matches, the error stays there displayng that it is not matching and I cannot figure out why is it doing this.

Another example of pattern not behaving as expected can be found in the code below:

<span>System ID</span>
          <span class="item item-input">
                    <input type="text"
                           ng-model="userRegistration.id"
                           placeholder="system id"
                           name="systemID"
                           ng-minlength="6"
                           ng-maxlength="6"
                           pattern="/:/"
                           required
                           ng-class="{'invalid-input': userRegistrationForm.systemID.$touched && userRegistrationForm.systemID.$invalid }">
                </span>
          <!-- Form validation messages -->
          <div role="alert" class="error-message" ng-messages="userRegistrationForm.systemID.$error" ng-show="userRegistrationForm.systemID.$touched">
            <p ng-message="required">This field is required</p>
            <p ng-message="pattern">Colons not required!</p>
            <p ng-message="minlength">This field is too short</p>
            <p ng-message="maxlength">This field is too long</p>
          </div>

I need to check if colons are added in the input, and display and error if they are. The proble, as above, is that even if colons are not there, the message is still displayed.

What am I missing? I'm clearly using ng-pattern and ng-messages wrong, but can't understand why.

Any help would be really appreciated.

Codepen with both examples here: http://codepen.io/NickHG/pen/NNZYwK?editors=1010

Thanks

Upvotes: 0

Views: 1148

Answers (1)

thepio
thepio

Reputation: 6253

I used a little different approach to get this to work with ng-messages. I made a custom directive like this:

.directive('compareTo', function() {
  return {
    require: "ngModel",
    scope: {
      otherModelValue: "=compareTo"
    },
    link: function(scope, element, attributes, ngModel) {

      ngModel.$validators.compareTo = function(modelValue) {
        return modelValue == scope.otherModelValue;
      };

      scope.$watch("otherModelValue", function() {
        ngModel.$validate();
      });
    }
  };

});

And display the error with it like this:

<div role="alert" class="error-message" 
ng-messages="userRegistrationForm.conf.$error" 
ng-show="userRegistrationForm.conf.$touched">
  <p ng-message="required">This field is required</p>
  <p ng-message="compareTo">Password not matching!</p>
</div>  

For further information and a demo please see the link below.

Codepen demo: http://codepen.io/thepio/pen/rLNBWr?editors=1010

EDIT based on comment:

Here is an example with using ng-pattern (no directive needed): http://codepen.io/thepio/pen/zBYOPy?editors=1010

I set a ng-change function to your first input and set a regexp in the controller when it's changed. Then I bind it to the ng-pattern of the confirmation input and show the ng-messages accordingly.

Upvotes: 2

Related Questions