J'ai actuellement une directive angulaire qui valide un mot de passe et confirme le champ de mot de passe comme correspondant. Cela fonctionne à un point, il jette une erreur lorsque les mots de passe ne correspondent pas. Cependant, l'erreur ne sera rejetée que lorsque vous aurez entré des données dans les deux champs. Comment puis-je faire en sorte que l'erreur pour les mots de passe incompatibles soit renvoyée dès que vous entrez des données dans un champ ou dans un autre?
Voici la directive (il faut l'ajouter aux deux champs qui doivent correspondre):
.directive('passwordVerify', function() {
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 || val1 === val2);
};
}
};
});
Et voici la directive dans ma forme:
<div class="small-5 columns">
<div class="small-12 columns">
<label>
Password
<input
ng-class="{ notvalid: submitted && add_user_form.user_password.$invalid }"
class="instructor-input"
id="user_password"
type="password"
name='user_password'
placeholder="password"
value=''
required
ng-model="user.user_password"
password-verify="[[user.confirm_password]]"
>
</label>
<p class="help-text">
<span class=" ">Required</span>
</p>
<div
class="help-block"
ng-messages="add_user_form.user_password.$error"
ng-show="add_user_form.user_password.$touched || add_user_form.user_password.$dirty"
>
<span class="red">
<div ng-messages-include="/app/views/messages.html" ></div>
</span>
</div>
</div>
<div class="small-12 columns">
<label>
Confirm Password
<input
ng-class="{ notvalid: submitted && add_user_form.confirm_password.$invalid }"
class="instructor-input"
id="confirm_password"
ng-model="user.confirm_password"
name="confirm_password"
type="password"
placeholder="confirm password"
name="user_confirm_passsword"
required
password-verify="[[user.user_password]]"
>
</label>
<p class="help-text">
<span class=" ">
Enter matching password
</span>
</p>
<div
class="help-block"
ng-messages="add_user_form.confirm_password.$error"
ng-show="add_user_form.confirm_password.$dirty || add_user_form.confirm_password.$touched "
>
<span class="red">
<div
ng-messages-include="/app/views/messages.html"
></div>
</span>
</div>
</div>
Il suffit de changer le dernier chèque:
ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
à:
ngModel.$setValidity('passwordVerify', val1 === val2);
Voici une version working:
(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>
J'espère que ça aide.
Voici une solution de travail simple. Nous pouvons simplement utiliser $validators
introduit dans Angular 1.3.0 pour obtenir le même résultat:
var app = angular.module("sa", []);
app.controller("FooController", function($scope) {
});
app.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
ngModel.$validators.myPwdInvalid = function(modelValue, viewValue) {
return viewValue === scope.$eval(attrs.passwordVerify);
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<form name="add_user_form" ng-app="sa" ng-controller="FooController">
<div class="small-12 columns">
<label>Password
<input ng-class="{ notvalid: add_user_form.user_password.$invalid }"
type="password" name='user_password' placeholder="password" required
ng-model="user.user_password" password-verify="user.confirm_password">
</label>
<div class="help-block" ng-messages="add_user_form.user_password.$error"
ng-show="add_user_form.user_password.$error.$dirty || add_user_form.user_password.$touched">
<div ng-messages="myPwdInvalid">Password do not match</div>
</div>
</div>
<div class="small-12 columns">
<label>Confirm Password
<input ng-class="{ notvalid: add_user_form.confirm_password.$invalid }"
ng-model="user.confirm_password"
name="confirm_password" type="password" placeholder="confirm password" required
password-verify="user.user_password">
</label>
<div class="help-block" ng-messages="add_user_form.confirm_password.$error"
ng-show="add_user_form.confirm_password.$error.$dirty || add_user_form.confirm_password.$touched">
<div ng-messages="myPwdInvalid">Password do not match</div>
</div>
</div>
</form>
Voici une solution facile à comprendre:
<input class="form-control" type="password" name="newpass" ng-model="newpass">
<input class="form-control" type="password" name="confirmpass" ng-model="confirmpass">
<div ng-show="confirmpass != newpass"><hr>Password not matched</div>
C'est ce qui a fonctionné pour moi (laid et hackish):
HTML:
<h1>Password Verification</h1>
<form name="pw" ng-controller="pw">
<p>
<label for="password">New Password
<input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword">
<p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.user_password.$error.required">This field is required</p>
</label>
</p>
<p>
<label for="password">Confirm Password
<input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password">
<p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.confirm_password.$error.required">This field is required</p>
</label>
</p>
</form>
Puis le script:
angular.module('app', [])
.controller('pw', ['$scope', function($scope){
$scope.user_password = "";
$scope.confirm_password = "";
}])
.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
scope.$watch(attrs.ngModel, function() {
if (scope.confirm_password === scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', true);
scope.pw.user_password.$setValidity('passwordVerify', true);
} else if (scope.confirm_password !== scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', false);
scope.pw.user_password.$setValidity('passwordVerify', false);
}
});
}
};
});