0

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

Nick
  • 13,493
  • 8
  • 51
  • 98

1 Answers1

2

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.

thepio
  • 6,193
  • 5
  • 35
  • 54
  • Thanks for the example above, I'll keep that in mind. But do you have an idea of why the default build in method is not working properly? – Nick May 27 '16 at 11:04
  • I updated my answer with a solution like you had. Only difference simply is to make up the regexp in the controller and bind that to the `ng-pattern`. Also my regexp is a little different. – thepio May 27 '16 at 11:25
  • Thanks for the update, but if I type 'a' as password, and 'a' as confirm, the message is still there like it was before – Nick May 27 '16 at 11:27
  • 1
    Oh yeah my bad. I updated the second codepen once again. Just need to check for the `minlength` attribute of the first input before showing any errors. – thepio May 27 '16 at 11:31
  • Thank you, it is working now. Any idea for the other example? the colon one? – Nick May 27 '16 at 11:36
  • 1
    No problem. Let me check the other one. I thought it was just an alternative example or something :P – thepio May 27 '16 at 11:37
  • 1
    Updated the second demo again to contain the validation for the colon also. I used `ng-form` to set the password checks in their own `ng-messages` validation. – thepio May 27 '16 at 12:26