Password-Check Directive in Angularjs

password-check directive in angularjs

This should solve it:

View:

<div ng-controller='Ctrl'>
<form name='form'>
<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<div ng-show="form.password.$error.required">
Field required</div>
<input ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">
<div ng-show="form.confirm_password.$error.required">
Field required!</div>
<div ng-show="form.confirm_password.$error.passwordVerify">
Fields are not equal!</div>
</form
</div>

Directive

var app = angular.module('myApp', []);

app.directive("passwordVerify", function() {
return {
require: "ngModel",
scope: {
passwordVerify: '='
},
link: function(scope, element, attrs, ctrl) {
scope.$watch(function() {
var combined;

if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + ctrl.$viewValue;
}
return combined;
}, function(value) {
if (value) {
ctrl.$parsers.unshift(function(viewValue) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
ctrl.$setValidity("passwordVerify", false);
return undefined;
} else {
ctrl.$setValidity("passwordVerify", true);
return viewValue;
}
});
}
});
}
};
});

Validating Password And Confirm Password Fields Whenever One Or The Other Fields Model Changes (Each Keystroke) With Angular Directive

Just change the last check:

ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);

to:

ngModel.$setValidity('passwordVerify', val1 === val2);

Here's a working version:

(function() {  "use strict";  angular    .module('app', ['ngMessages'])    .controller('mainCtrl', mainCtrl)    .directive('passwordVerify', passwordVerify);
function mainCtrl($scope) { // Some code }
function passwordVerify() { return { restrict: 'A', // only activate on element attribute require: '?ngModel', // get a hold of NgModelController link: function(scope, elem, attrs, ngModel) { if (!ngModel) return; // do nothing if no ng-model
// watch own value and re-validate on change scope.$watch(attrs.ngModel, function() { validate(); });
// observe the other value and re-validate on change attrs.$observe('passwordVerify', function(val) { validate(); });
var validate = function() { // values var val1 = ngModel.$viewValue; var val2 = attrs.passwordVerify;
// set validity ngModel.$setValidity('passwordVerify', val1 === val2); }; } } }})();
<html ng-app="app">
<head> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script></head>
<body ng-controller="mainCtrl"> <form name="add_user_form"> <div class="col-md-12"> <div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$dirty && add_user_form.user_password.$invalid }"> <p class="help-text">Enter password</p> <input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}"> <div class="help-block" ng-messages="add_user_form.user_password.$error" ng-if="add_user_form.user_password.$dirty"> <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> <p ng-message="required">This field is required</p> <p ng-message="passwordVerify">No match!</p> </div> </div> <div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$dirty && add_user_form.confirm_password.$invalid }"> <p class="help-text">Enter matching password</p> <input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}"> <div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-if="add_user_form.confirm_password.$dirty"> <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> <p ng-message="required">This field is required</p> <p ng-message="passwordVerify">No match!</p> </div> </div> </div> </form></body>
</html>

Angular Compare Password Directive

To make it work you should change ng-show condition from signUpForm.confirmPassword.$error to signUpForm.confirmPassword.$error.kaCompareTo

To achieve same behaviour, you can use AngularJS "ng-pattern" attribute instead of creating a custom directive. IMHO it is even better solution, because it returns error only if "confirmPassword" is not empty:

<input 
type="text"
placeholder="Re-enter Password"
name="confirmPassword"
required=""
ng-pattern="user.password"
ng-model="user.confirmPassword"
class="form-control"/>
<div
ng-show="signUpForm.confirmPassword.$error.pattern"
class="form-group has-error">
<label class="control-label">Passwords Do Not Match</label>
</div>

Custom password validation directive not applying

The problem comes from your AngularJS version, I updated it in the jsfiddle to : AngularJS 1.5.6 (CDN link) and it works (new jsfiddle).

Confirm password validation angularjs material design

You have to create a Custom Directive. Try this.

<div data-ng-controller="PasswordController as vmPassword">
<form name="passwordForm">
<md-input-container class="md-block" flex-gt-sm>
<label>Password</label>
<input type="password"
name="password"
ng-model="vmPassword.password"
required
/>
<div ng-messages="passwordForm.password.$error" role="alert" class="form-errors first-name-error">
<div ng-message="required">Password is required.</div>
</div>
</md-input-container>

<md-input-container class="md-block" flex-gt-sm>
<label>Confirm Password</label>
<input type="password"
name="confirm_password"
ng-model="vmPassword.confirm_password"
required
compare-to="vmPassword.password"
/>
<div ng-messages="passwordForm.confirm_password.$error" role="alert" class="form-errors first-name-error">
<div ng-message="required">Password is required.</div>
<div ng-message="compareTo">Passwords do not match</div>
</div>
</md-input-container>
</form>
</div>

Custom Directive

(function () {
"use strict";

angular.module('app').directive('compareTo', compareTo);

compareTo.$inject = [];

function compareTo() {

return {
require: "ngModel",
scope: {
compareTolValue: "=compareTo"
},
link: function(scope, element, attributes, ngModel) {

ngModel.$validators.compareTo = function(modelValue) {

return modelValue == scope.compareTolValue;
};

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

Goodluck .! :)

Demo here - http://embed.plnkr.co/UK4G4Lm5BCNNe5SWoA9r/

AngularJs- Form validation directive. The password confirm is always invalid

I can't test it now, but I believe $parsers expects you to return a value unless you have a parser error.

Try to add a return in your code:

ctrl.$parsers.unshift(function (viewValue) {
var noMatch = viewValue != scope.regForm.password.$viewValue;
ctrl.$setValidity('noMatch', !noMatch);
return viewValue;
});

Directive that checks password strength AND confirms match

The code above has errors (for one the ctrl.$parsers.unshift(...) part is outside the function; I guess these are typos).

Anyway, changing the parser function to always return the viewValue, plus a few minor changes that may not be important for this (e.g. the checks are not kept in scope, rather in local vars, their value is boolean, not "valid"/undefined), does the trick:

app.directive('match',['$parse', function ($parse) {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, elem, attrs, ctrl) {
//This part does the matching
scope.$watch(function() {
return (ctrl.$pristine && angular.isUndefined(ctrl.$modelValue)) || $parse(attrs.match)(scope) === ctrl.$modelValue;
}, function(currentValue) {
ctrl.$setValidity('match', currentValue);
});

//This part is supposed to check the strength
ctrl.$parsers.unshift(function(viewValue) {
var pwdValidLength, pwdHasLetter, pwdHasNumber;

pwdValidLength = (viewValue && viewValue.length >= 8 ? true : false);
pwdHasLetter = (viewValue && /[A-z]/.test(viewValue)) ? true : false;
pwdHasNumber = (viewValue && /\d/.test(viewValue)) ? true : false;

if( pwdValidLength && pwdHasLetter && pwdHasNumber ) {
ctrl.$setValidity('pwd', true);
} else {
ctrl.$setValidity('pwd', false);
}
return viewValue;
});
},
};
}]);

See fiddle: http://jsfiddle.net/EHJq8/

Password Verification in angular js

I've struggled with this, and it's messy. I see no help in a directive, because logically, all that's needed is to constrain one value to match another by validation. All I needed was ng-pattern and a helper filter to escape a string into a tight regular expression. (Note I'm checking emails, but the concept is identical.)

My code:

<input type="email" name="email" ng-model="data.email" 
required placeholder="jane.doe@example.com">
<input type="email" name="verify" ng-model="verify"
required ng-pattern="data.email | quotepattern">

The quotepattern filter implementation is:

function(input) {
if (!! input) {
return "^" + input.replace(/(\W)/g, "\\$1") + "$";
} else {
return input;
}
}

This does a valid binding on both, and checks for validity. If the first value changes, both controls get updated. If the verify control value changes, only that control is affected.

To me, this is infinitely simpler than directive hackery, and conceptually more correct too, since logically all you need to do is check for a string match in the verify control. Engineering an entire new control with custom editing logic to do that is breeding an entire yak only to shave it.



Related Topics



Leave a reply



Submit