angularjsangularjs-directiveangularjs-ng-modelangularjs-ng-form

Passing Information to Directive to Match Passwords


I'm trying to add an errors to my floating placeholder labels when certain conditions are met in my controller

However, I'm not sure the best way to go about this and my current implementing doesn't seem to be detecting the attribute change in the directive (custom-error stays set to "test").

Here's what I've got right now:

HTML:

<input type="password" float-placeholder
       custom-error="test" placeholder="Confirm password"
       required name="passwordSecond" id="passwordSecond"
       ng-model="vs.PasswordSecond" />

Directive:

angular.module('myApp').directive('floatPlaceholder', function ($window) {
  return {
    restrict: 'A',
    scope: {
      customError: '@'
    },
    link: function (scope, element, attrs) {
      element.after("<label class='floating-placeholder'>" + attrs.placeholder + "</label>");
      var label = angular.element(ele.parent()[0].getElementsByClassName('floating-placeholder'));

      element.on('blur', function() {
        if (ele.val().length > 0) { 
          if (scope.customError) {
            label.text(attrs.placeholder + ' - ' + scope.customError);
          }
        }
      }
    }
  };
});

Controller:

angular.module('myApp').controller('SignupController', function factory() {
  _this.confirmPassword = () => {
    if(_this.PasswordFirst !== _this.PasswordSecond){
      angular.element(signupForm.passwordSecond).attr('custom-error', _this.Error);
    }
  }
});

I'm using Angular 1.6


Solution

  • Validator Directive which Matches Passwords

    To have a form match password inputs, create a custom directive that hooks into the ngModelController API ($validators):

    app.directive("matchWith", function() {
      return {
        require: "ngModel",
        link: postLink
      };
      function postLink(scope,elem,attrs,ngModel) {
        ngModel.$validators.match = function(modelValue, viewValue) {
            if (ngModel.$isEmpty(modelValue)) {
              // consider empty models to be valid
              return true;
            }
            var matchValue = scope.$eval(attrs.matchWith);
            if (matchValue == modelValue) {
              // it is valid
              return true;
            }
            // it is invalid
            return false;
        };
      }
    })
    

    For more information, see AngularJS Developer Guide - Forms - Modifying Built-in Validators

    The DEMO

    angular.module("app",[])
    .directive("matchWith", function() {
      return {
        require: "ngModel",
        link: postLink
      };
      function postLink(scope,elem,attrs,ngModel) {
        ngModel.$validators.match = function(modelValue, viewValue) {
            if (ngModel.$isEmpty(modelValue)) {
              // consider empty models to be valid
              return true;
            }
            var matchValue = scope.$eval(attrs.matchWith);
            if (matchValue == modelValue) {
              // it is valid
              return true;
            }
            // it is invalid
            return false;
        };
      }
    })
    <script src="//unpkg.com/angular/angular.js"></script>
      <body ng-app="app">
        <form name="form1">
            <input type="password" name="password1" required
                   placeholder="Enter password"
                   ng-model="vm.password1" />
            <br>
            <input type="password" name="password2" required
                   placeholder="Confirm password"
                   ng-model="vm.password2"
                   match-with="vm.password1"
                   ng-model-options="{updateOn: 'blur'}" />
            <br>
            <p ng-show="form1.password2.$error.match">
              Passwords don't match
            </p>
            <input type="submit" value="submit" />
        </form>
      </body>