AngularJS password confirmation noMatch not working? - angularjs

I have this script here:
angular.module('UserValidation', []).directive('validPasswordC', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var noMatch = viewValue != scope.signupForm.password.$viewValue
ctrl.$setValidity('noMatch', !noMatch)
})
}
}
});
And here's the html:
<div class="fieldset" ng-class="{'has-error':formData.password.$invalid && !formData.password.$pristine}">
<label>Password</label>
<input type="password" id="password" name="password" ng-model="formData.password" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" placeholder="password" required />
<p ng-show="signupForm.password.$error.required" class="error">*</p>
<p ng-show="signupForm.password.$error.minlength" class="error">
Passwords must be between 8 and 20 characters.</p>
<p ng-show="signupForm.password.$error.pattern" class="error">
Must contain one lower & uppercase letter, and one non-alpha character (a number or a symbol.)</p>
</div>
<div class="fieldset" ng-class="{'has-error':formData.password_c.$invalid && !formData.password_c.$pristine}">
<label for="password_c">Confirm Password</label>
<input type="password" id="password_c" name="password_c" ng-model="formData.password_c" placeholder="confirm password" valid-password-c required />
<p ng-show="signupForm.password_c.$error.noMatch" class="error">Passwords do not match.</span>
<p ng-show="signupForm.password_c.$error.required" class="error">*</p>
</div>
The character validation for password is working, but the "noMatch" function for confirm password is not working.
What might be the problem? Thanks! :)

You need to pass your original password to directive as well/
Please see working demo below
var app = angular.module('app', []);
app.directive('validPasswordC', function() {
return {
require: 'ngModel',
scope: {
reference: '=validPasswordC'
},
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue, $scope) {
var noMatch = viewValue != scope.reference
ctrl.$setValidity('noMatch', !noMatch);
return (noMatch)?noMatch:!noMatch;
});
scope.$watch("reference", function(value) {;
ctrl.$setValidity('noMatch', value === ctrl.$viewValue);
});
}
}
});
app.controller('homeCtrl', function($scope) {
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<p>Password:{{formData.password}}</p>
<form name="signupForm">
<div class="fieldset" ng-class="{'has-error':formData.password.$invalid && !formData.password.$pristine}">
<label>Password</label>
<input type="password" id="password" name="password" ng-model="formData.password" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" placeholder="password" required />
<p ng-show="signupForm.password.$error.required" class="error">*</p>
<p ng-show="signupForm.password.$error.minlength" class="error">
Passwords must be between 8 and 20 characters.</p>
<p ng-show="signupForm.password.$error.pattern" class="error">
Must contain one lower & uppercase letter, and one non-alpha character (a number or a symbol.)</p>
</div>
<div class="fieldset" ng-class="{'has-error':formData.password_c.$invalid && !formData.password_c.$pristine}">
<label for="password_c">Confirm Password</label>
<input type="password" id="password_c" name="password_c" ng-model="formData.password_c" placeholder="confirm password" valid-password-c="formData.password" required />
<p ng-show="signupForm.password_c.$error.noMatch" class="error">Passwords do not match.</span>
<p ng-show="signupForm.password_c.$error.required" class="error">*</p>
</div>
</form>
</div>
</div>

The easiest is this one.But i don't know this is the good way of coding.
<input ng-model="password" name="user_password" type="password" ng-required="true" >
<input ng-model="confirmPassword" name="user_password" type="password" ng-required="true" >
<span ng-show="pasword !== confirmPassword">Password mismatch</span>

The following also will work to verify the confirm password.
<div ng-app="myapp" ng-controller="mainController as mnCtrl">
<form name="mnCtrl.useradd" ng-submit="mnCtrl.frmAdd()" novalidate role="form">
<input ng-model="mnCtrl.fields.password" name="user_password" type="password" ng-required="true" >
<input ng-model="mnCtrl.fields.cpassword" name="user_cpassword" type="password" ng-required="true" >
<div ng-show=" mnCtrl.useradd.user_cpassword.$viewValue != '' && (mnCtrl.useradd.user_password.$viewValue != mnCtrl.useradd.user_cpassword.$viewValue) ">Fields do not match!</div>
</form>
</div>

Related

Add a custom validation using Angular Auto Validate

First, I'm using Angular Auto Validate and it's working as expected, but I want to add a custom validation to compare passwords.
Here's my code actually:
<form role="form" name="changePasswordForm" novalidate="novalidate" ng-submit="changePassword()">
<div class="box-body">
<div class="form-group">
<label for="oldPassword">Old Password</label>
<input type="password" class="form-control" id="txtOldPassword" name="oldPassword" ng-model="data.oldPassword" placeholder="Old password" required="required" ng-pattern="/^[A-Za-z]+$/" ng-minlength="6" ng-maxlength="10" ng-pattern-err-type="badOldPassword">
</div>
<div class="form-group">
<label for="newPassword">New Password</label>
<input type="password" class="form-control" id="txtNewPassword" name="newPassword" ng-model="data.newPassword" placeholder="New password" required="required" ng-pattern="/^[A-Za-z]+$/" ng-minlength="6" ng-maxlength="10" ng-pattern-err-type="badNewPassword">
</div>
<div class="form-group">
<label for="confirmNewPassword">Confirm New Password</label>
<input type="password" class="form-control" id="txtConfirmNewPassword" name="confirmNewPassword" ng-model="data.confirmNewPassword" placeholder="Confirm new password" required="required" ng-pattern="/^[A-Za-z]+$/" ng-minlength="6" ng-maxlength="10" ng-pattern-err-type="badConfirmNewPassword">
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
var userApp = angular
.module("userModule", ['jcs-autoValidate'])
.run(function(defaultErrorMessageResolver) {
defaultErrorMessageResolver.getErrorMessages().then(function(errorMessages) {
errorMessages['badOldPassword'] = 'Old password must contain only alphabets.';
errorMessages['badNewPassword'] = 'New password must contain only alphabets..';
errorMessages['badConfirmNewPassword'] = 'Confirm password must contain only alphabets.';
})
})
.controller('userController', function($scope, $http, $log) {
$scope.data = {};
$scope.changePassword = function() {
alert('form submitted');
}
});
You should create a directive for this, as below:
angular.module('app', ['jcs-autoValidate'])
.controller('mainCtrl', function($scope) {
})
.directive('confirmPassword', function(defaultErrorMessageResolver) {
defaultErrorMessageResolver.getErrorMessages().then(function(errorMessages) {
errorMessages['confirmPassword'] = 'Please ensure the passwords match.';
});
return {
restrict: 'A',
require: 'ngModel',
scope: {
confirmPassword: '=confirmPassword'
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.confirmPassword = function(modelValue) {
return modelValue === scope.confirmPassword;
};
scope.$watch('confirmPassword', function() {
ngModel.$validate();
});
}
};
});
<!DOCTYPE html >
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<script src="https://cdn.rawgit.com/jonsamwell/angular-auto-validate/master/dist/jcs-auto-validate.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body ng-controller="mainCtrl">
<div class="container main-content">
<form novalidate="novalidate">
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" ng-model="formModel.password" required="" ng-minlength="6" ng-maxlength="12" />
</div>
<div class="form-group">
<label for="exampleInputPassword">Confirm Password</label>
<input type="password" class="form-control" id="passwordConfirm" placeholder="Confirm Password" ng-model="formModel.confirmPassword" required="" ng-minlength="6" ng-maxlength="12" confirm-password="formModel.password" />
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Register
</button>
</div>
</form>
</div>
</body>
</html>

ng-disable not working for hide submit button

Hi I have a problem with ng-disabled for my submit button. Here is my code:
<div class="container">
<form class="form-login" role="form" name="form">
<h2 class="form-login-heading">Sign up</h2>
<br />
<input type="text" class="form-control" placeholder="Username" name="username" data-ng-model="registration.username" ng-minlength="5" ng-maxlength="20" ng-pattern="/^[A-z][A-z0-9]*$/" required />
<span ng-show="form.username.$error.required && form.username.$dirty">required</span>
<br />
<input type="password" id="password" class="form-control" placeholder="Password" name="password" data-ng-model="registration.plainPassword" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" required />
<span ng-show="form.password.$error.required && form.password.$dirty">required</span>
<br />
<input type="password" id="password_c" class="form-control" placeholder="Confirm password" name="password_c" data-ng-model="registration.password_c" valid-password-c required />
<br />
<input type="email" id="email" class="form-control" placeholder="email" name="email" data-ng-model="registration.email" required>
<span ng-show="form.email.$error.required && form.email.$dirty">required</span>
<br />
<button class="btn btn-lg btn-info btn-block" type="submit" ng-disabled="form.$invalid" data-ng-click="signUp()">Submit</button>
<div data-ng-hide="message == ''" data-ng-class="(savedSuccessfully) ? 'alert alert-success' : 'alert alert-danger'">
{{message}}
</div>
</form>
I tried ng-disabled="!form.$valid" but the code is still not working. Console doesn't show any error. Can someone help me? Thank you
we solve the problem, thnx to #Silvinus, he save my life and time
The problem was in my directive, for password confirmation. I forget add return. This is how it looks
.directive('validPasswordC', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var noMatch = viewValue != scope.form.password.$viewValue
ctrl.$setValidity('noMatch', !noMatch);
return viewValue; //this is what i forget to add
});
}
};
});
I copied your code and it working for me. Maybe the directive 'valid-password-c' if wrong.

AngularJs user registration form: add a "repeat password" & check that passwords match

I would like to use the AngularJs user registration from http://jasonwatmore.com/post/2015/03/10/AngularJS-User-Registration-and-Login-Example.aspx However, it only prompts for the password once.
I would like to add a "repeat password field and also verify that both passwords are the same.
What am I doing wrong here?
<div class="col-md-6 col-md-offset-3">
<h2>Register</h2>
<div ng-show="vm.error" class="alert alert-danger">{{vm.error}}</div>
<form name="form" ng-submit="vm.register()" role="form">
<div class="form-group" ng-class="{ 'has-error': form.name.$dirty && form.name.$error.required }">
<label for="name">Full name</label>
<input type="text" name="name" id="name" class="form-control" ng-model="vm.user.name" required />
<span ng-show="form.name.$dirty && form.name.$error.required" class="help-block">First name is required</span>
</div>
<div class="form-group" ng-class="{ 'has-error': form.email.$dirty && form.email.$error.required }">
<label for="email">Email address</label>
<input type="text" name="email" id="email" class="form-control" ng-model="vm.user.email" required />
<span ng-show="form.email.$dirty && form.email.$error.required" class="help-block">Last name is required</span>
</div>
<div class="form-group" ng-class="{ 'has-error': form.username.$dirty && form.username.$error.required }">
<label for="username">Requested username</label>
<input type="text" name="username" id="username" class="form-control" ng-model="vm.user.username" required />
<span ng-show="form.username.$dirty && form.username.$error.required" class="help-block">Username is required</span>
</div>
<div class="form-group" ng-class="{ 'has-error': form.password.$dirty && form.password.$error.required }">
<label for="password">Password</label>
<input type="password" name="password" id="password" class="form-control" ng-model="vm.user.password" required />
<span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
- I am adding this, but it doesn't work :-(
<div class="form-group" ng-class="{ 'has-error': form.password2.$dirty && form.password2.$error.required }">
<label for="password2">Repeat password</label>
<input type="password" name="password2" id="password2" class="form-control" ng-model="vm.user.password2" required />
<span ng-show="form.password2.$dirty && form.password2.$error.required" class="help-block">Password is required</span>
<span ng-show="form.password2.$dirty && form.password2.$error.required && form.password2 != form.password" class="help-block">Passwords do not match</span>
-
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary">Register</button>
<img ng-if="vm.dataLoading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
Cancel
</div>
</form>
</div>
This logic belongs in your controller (or factory, etc), not in the view. You can do something like:
vm.register = function() {
if (vm.user.password !== vm.user.password2) {
vm.alert = 'Passwords must match';
return;
}
...
}
You can also use directive:
.directive('passwordError', function(){
return {
restrict: 'A',
require: 'ngModel',
scope : {
message : "="
},
link : function(scope, element, attrs, ngModel) {
element.on('keydown', function(){
scope.message = '';
return ngModel.$setValidity('passwordError', true);
})
}
}
})
.directive('pwCheck', function(){
return {
require : 'ngModel',
scope : {
newPassword: '=match'
},
link:function(scope, element, attrs, ngModel){
scope.$watch('newPassword', function(){
ngModel.$setValidity('matchError', element.val() === scope.newPassword);
})
element.on('keyup', function(){
scope.$apply(function(){
ngModel.$setValidity('matchError', element.val() === scope.newPassword);
})
})
}
}
})
Here is an example
The check in your ng-show doesn't work because you're trying to compare angular objects not the values of inputs. form.password2 != form.password should be form.password2.$modelValue != form.password.$modelValue.
And second you don't need the form.password2.$error.required check for matching validation. It ruins logic
See plunker. Hope this helps

How to show different type of custom messages at input in form validation with angularjs

I have built a from and trying to implement validation process with angularjs. At my source code, you will see I have three input fields:
Email
Password
Confirm Password
At Email, I can show a 'Required message' and a 'Custom Message' by doing this:
<input type="email" class="form-control" id="inputEmail" name="inputEmail" placeholder="Email" ng-model="email" required>
<p ng-show="createLogin.inputEmail.$error.required">This field is required</p>
<p ng-show="createLogin.inputEmail.$error.email">Enter a valid email<p>
This is completely fine. But, following the same procedure at other two input fields(Password & Confirm Password), I can't show the 'Custom Messages'! Only 'Required Messages' are shown. How can I fix this? This is the code which I have used for password:
<input type="password" class="form-control" id="createPassword" name="createPassword" placeholder="Password" ng-model="password" password-validate required>
<div ng-show="createLogin.createPassword.$error.required"><p>This field is required</p></div>
<div ng-show="createLogin.createPassword.$error.password">
<p>Custom Messages:</p>
</div>
And for Confirm Password:
<input type="password" class="form-control" id="confirmPassword" name="confirmPassword" placeholder="Password" ng-model="verifyPass" required data-password-verify="password">
<p ng-show="createLogin.confirmPassword.$error.required">This field is required</p>
<p ng-show="createLogin.confirmPassword.$error.verifyPass">Password don't match<p>
So, how can I show the Custom Messages for Password and Confirm Password filed too like Email filed?
Here is my Plunker work
Since your custom directive set validation key to pwd (ctrl.$setValidity('pwd', true)) you need to use it in HTML in expressions like:
<div ng-show="createLogin.createPassword.$error.pwd">
<p>Password must meet the following requirements:</p>
<ul>
<li ng-class="pwdHasLetter">At least <strong>one letter</strong></li>
<li ng-class="pwdHasNumber">At least <strong>one number</strong></li>
<li ng-class="pwdValidLength">Be at least <strong>8 characters</strong></li>
</ul>
</div>
The same issue with password verification field, key should be passwordVerify:
<p ng-show="createLogin.confirmPassword.$error.passwordVerify">Password don't match</p>
Demo: http://plnkr.co/edit/zMbCxcdkYggOdvXYkMX1?p=preview
Please have a look at the below link
http://plnkr.co/edit/iSFp3n4PSDTM6pRofXc2
Following is the directive for matching passwords.
Directive
app.directive('pwdMatch', function () {
return {
require: 'ngModel',
restrict: 'A',
scope: {
pwdMatch: '='
},
link: function (scope, elem, attrs, ctrl) {
scope.$watch(function () {
var modelValue = ctrl.$modelValue || ctrl.$$invalidModelValue;
return (ctrl.$pristine && angular.isUndefined(modelValue)) || scope.pwdMatch === modelValue;
}, function (currentValue) {
ctrl.$setValidity('pwdMatch', currentValue);
});
}
};
})
HTML
<div class="form-group">
<label for="password" class="col-sm-4 control-label">Password</label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password" placeholder="Enter password"
ng-model="user.password" name="password" required="true"
ng-pattern="/^(?=.*[0-9])(?=.*[A-Za-z])[a-zA-Z0-9~!##$%^&*]{6,15}$/">
<span ng-show="signUpForm.password.$dirty && signUpForm.password.$error.required">
<small class="text-danger">Please enter a password.</small>
</span>
<span ng-show="signUpForm.password.$dirty && !signUpForm.password.$error.required && signUpForm.password.$error.pattern">
<small class="text-danger">Password should have 6 to 15 characters with alphabets and digits</small>
</span>
</div>
</div>
<div class="form-group">
<label for="confirmPassword" class="col-sm-4 control-label">Confirm Password</label>
<div class="col-sm-8">
<input type="password" class="form-control" name="confirmPassword" id="confirmPassword"
placeholder="Confirm password" ng-model="user.confirmPassword" required="true"
data-pwd-match="user.password">
<span ng-show="signUpForm.confirmPassword.$dirty && (signUpForm.confirmPassword.$error.required || signUpForm.confirmPassword.$error.pwdMatch)">
<small class="text-danger">Passwords do not match.</small>
</span>
</div>
</div>
Hope this is what you are looking for.

I cannot valid a form with password and password confirm with angular 1.3.2

I have a register form with input password and passwordConfirm as follow :
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="inputPassword" id="inputPassword" ng-minlength=8 placeholder="Password" ng-model="user.password" required>
</div>
<!-- error -->
<div class="error" ng-show="userForm.inputPassword.$dirty && userForm.inputPassword.$invalid">
<small class="error" ng-show="userForm.inputPassword.$error.required"> Your password is required. </small>
<small class="error" ng-show="userForm.inputPassword.$error.minlength"> Your password is required to be at least 8 characters </small>
</div>
</div>
<div class="form-group">
<label for="inputPassword2" class="col-sm-2 control-label">Password</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="passwordConfirm" id="passwordConfirm" placeholder="Check your password" ng-model="passwordConfirm" required pw-check="user.password">
</div>
<!-- error -->
<div class="error" ng-show="userForm.passwordConfirm.$dirty && userForm.passwordConfirm.$invalid">
<small class="error" ng-show="userForm.passwordConfirm.$error.noMatch"> Passwords don't match </small>
</div>
</div>
In Chrome console, when the input are pristine (not yet filled), this is how it's look passwordConfirm:
<input type="password" class="form-control ng-pristine ng-untouched ng-invalid ng-invalid-required" name="passwordConfirm" id="passwordConfirm" placeholder="Check your password" ng-model="passwordConfirm" required="" pw-check="user.password">
When i fill the password, i have the following error classes :
<input type="password" class="form-control ng-invalid ng-dirty ng-invalid-parse ng-valid-no-match ng-touched" name="passwordConfirm" id="passwordConfirm" placeholder="Check your password" ng-model="passwordConfirm" required="" pw-check="user.password">
What is the ng-invalid-parse ? I did not find documentation on it. I think this parse error causes ng-invalid so my form is invalid.
pw-check is a directive defined as follow :
app.directive('pwCheck', [function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var noMatch = viewValue != scope.userForm.inputPassword.$viewValue
ctrl.$setValidity('noMatch', !noMatch)
})
}
}
}]);
How to resolve it please ?

Resources