Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a directive in AngularJS to validate email or password confirmation without DOM manipulation or jQuery?

I want to create a password / email confirmation directive in AngularJS, but all the ones I've seen so far rely on a lot of DOM poking or pulling in jQuery. I'd like to rely only on $scope properties if I can. What's the best way to do that?

like image 398
JoshGough Avatar asked Jul 04 '13 17:07

JoshGough


1 Answers

After looking at the numerous helpful ways to implement this kind of directive, I figured out how to do it without DOM manipulation or using jQuery. Here's a Plunk that shows how.

It involves using:

  • ng-model properties on the $scope for both input fields
  • $parse(expr)(scope) and a simple scope.$watch expression -- to evaluate the "match" property in the context of the current scope against the $modelValue of the control on which you add the match attribute directive.
  • Disabling the submit button if the $invalid property is true on the underlying form.

I hope this is useful to some. Here's the gist:

var app = angular.module('app', [], function() {} );

app.directive('match', function($parse) {
  return {
    require: 'ngModel',
    link: function(scope, elem, attrs, ctrl) {
      scope.$watch(function() {        
        return $parse(attrs.match)(scope) === ctrl.$modelValue;
      }, function(currentValue) {
        ctrl.$setValidity('mismatch', currentValue);
      });
    }
  };
});

app.controller('FormController', function ($scope) {
  $scope.fields = {
    email: '',
    emailConfirm: ''
  };

  $scope.submit = function() {
    alert("Submit!");
  };
});

Then, in HTML:

<!DOCTYPE html>
    <html ng-app="app">  
      <head lang="en">
        <meta charset="utf-8">
        <title>Custom Plunker</title>
        <link rel="stylesheet" href="style.css">
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <script src="app.js"></script>
      </head>  
      <body ng-controller="FormController">
        <form name='appForm' ng-submit='submit()'>
          <div class="control-group">
            <label class="control-label required" for="email">Email</label>
            <div class="controls">
              <input id="email" name="email" ng-model="fields.email" 
    class="input-xlarge" required="true" type="text" />
              <p class="help-block">[email protected]</p>
            </div>
          </div>
          <div class="control-group">
            <label class="control-label required" for="emailConfirm">Confirm Email</label>
            <div class="controls">
              <input name="emailConfirm" ng-model="fields.emailConfirm" 
    class="input-xlarge" required="true"
                type="text" match="fields.email" />
              <div ng-show="appForm.emailConfirm.$error.mismatch">
                <span class="msg-error">Email and Confirm Email must match.</span>
              </div>
            </div>
          </div>
          <button ng-disabled='appForm.$invalid'>Submit</button>
        </form>
      </body>
    </html>
like image 177
JoshGough Avatar answered Oct 05 '22 23:10

JoshGough