javascript - AngularJS 确认密码验证

标签 javascript css angularjs html dom

这里我遇到了以下指定第三点的问题(当用户更改密码值时)。

  • 测试场景:
    1. 用户正确输入所有字段 - [Button Enabled]
    2. 如果密码字段因不符合密码强度而无效,则创建帐户按钮处于禁用模式。
    3. 如果用户更改密码值但密码字段有效。例如:[Yash@123Yash@1234] 这里的确认字段值为 Yash@123。那么按钮应该处于禁用模式。

enter image description here

我已经通过访问 Parent Scope 进行了测试, 两个指令之间的 Scope 值。

function okPasswordDirective() {
    $element.on('blur change keydown', function( evt ) {
        if( ngPasswordModel.$valid ) {
            $scope.passwordVal = ngPasswordModel.$viewValue;
            console.log('Updated Val : ', $scope.passwordVal);
            $scope.updatePass();
        }
    }
}

function compareToDirective() {
    //use scope.$parent to associate the function called to directive function
    scope.$parent.updatePass = function() {
        console.log('$watch « Password Element Watcher.')
        console.log('Pswd: ',scope.$parent.passwordVal, '\t Cnfirm:', ngModel.$modelValue);
        //scope.registerForm.confirm.$invalid = true;
    }
}

updatePass() 函数中,我没有收到最后提交的密码值。当我点击确认字段时,它曾经得到。 但没有用,我无法通过使 confirm field as invalid 来禁用按钮。

var pswd = angular.element(document.getElementById('password')).scope().registerForm.password;
var cnfm = angular.element(document.getElementById('confirmedID')).scope().registerForm.confirm;
console.log('PSWD:', pswd, '\n CNFM:', cnfm);
console.log('Diff : ', pswd.$viewValue != cnfm.$viewValue);

if( pswd.$viewValue != cnfm.$viewValue ) {
    console.log('Result : ', (pswd.$dirty && cnfm.$dirty && cnfm.$valid && ( pswd.$viewValue != cnfm.$viewValue ) ) ? 'error' : 'noErr');
    cnfm.$invalid = true;
}

注册表代码:fiddle

<!-- HTML CODE -->
<body ng-app="loginModule">

 <div class="main-container">
  <div class="form-container">

   <h2 class="form-label">Sign Up</h2>
    <div class="form-container" data-ng-controller="registerController" >
        <form name="registerForm" role="form" data-ng-submit="formSubmit()">
            <div class="form-group"><!-- Display Name -->
                <div class="row">
                <div class="col-md-6 col-sm-6 col-xs-6  left">
                  <div class="error form-hint" 
                    data-ng-show="registerForm.firstname.$dirty && registerForm.firstname.$error.required" 
                    data-ng-cloak>{{"This field is required."}}
                    </div>
                    <input type="text" class="form-control" name="firstname" placeholder="First name" 
                    data-ng-class="(registerForm.firstname.$dirty && registerForm.firstname.$invalid) ? 'error' : ''"
                    data-ng-required="true" data-ng-model="firstName">
                  </div>

                  <div class="col-md-6 col-sm-6 col-xs-6  right">
                    <div class="error form-hint" 
                    data-ng-show="registerForm.lastname.$dirty && registerForm.lastname.$error.required" 
                    data-ng-cloak>{{"This field is required."}}
                    </div>
                    <input type="text" class="form-control" name="lastname" placeholder="Last name" 
                    data-ng-class="(registerForm.lastname.$dirty && registerForm.lastname.$invalid) ? 'error' : ''"
                    data-ng-required="true" data-ng-model="lastName">
                    </div>
                  </div>
                </div>
                </div>
            </div>

            <div class="form-group">
                <div class="error form-hint" 
                data-ng-show="registerForm.username.$dirty && registerForm.username.$error.required" 
                data-ng-cloak>{{"This field is required."}}
                </div>

                <input type="text" class="form-control" id="userid" name="username" placeholder="User name" 
                data-ng-class="(registerForm.username.$dirty && registerForm.username.$invalid) ? 'error' : ''"
                data-ng-required="true" data-ng-model="username">
            </div>

            <div class="form-group">
                <div class="error form-hint" 
                data-ng-show="registerForm.email.$dirty && registerForm.email.$error.required" 
                data-ng-cloak>{{"You can't leave this empty."}}
                </div>
                <div class="error form-hint" 
                data-ng-show="registerForm.email.$dirty && registerForm.email.$error.email" 
                data-ng-cloak>{{"The email address you provided isn't valid"}}</div>

                <input type="email" class="form-control" id="emailid" name="email" placeholder="Email address" 
                data-ng-class="(registerForm.email.$dirty && registerForm.email.$invalid) ? 'error' : ''"
                data-ng-required="true" data-ng-model="email77">
            </div>

            <div class="form-group">
                <div class="form-hint">
                To conform with our Strong Password policy,
                Use at least one letter, one numeral, one special character, and seven characters.
                </div>

                <input type="text" class="form-control" data-ok-password-directive
                id="password" name="password" placeholder="Password" data-ng-required="true" 
                data-ng-class="(registerForm.password.$dirty && registerForm.confirm.$dirty 
                && registerForm.confirm.$valid &&
                ( registerForm.password.$viewValue != registerForm.confirm.$viewValue ) ) ? 'error' : ''"
                data-ng-model="passwordModel">

                <div class="label password-count" 
                data-ng-class="passwordModel.length > 7 ? 'label-success' : 'label-danger'" 
                data-ng-cloak>{{ passwordModel | passwordCountFilter }}</div>

                <div class="strength-meter">
                    <div class="strength-meter-fill" data-strength="{{myModulePasswordMeter}}"></div>
                </div>
            </div>

            <div class="form-group">
                <div class="error form-hint" 
                data-ng-show="registerForm.confirm.$dirty && !registerForm.confirm.$empty && registerForm.confirm.$error.required" 
                data-ng-cloak>{{"You can't leave this empty."}}
                </div>
                <div class="error form-hint" 
                data-ng-show="registerForm.confirm.$dirty && registerForm.confirm.$invalid && !registerForm.confirm.$error.required" 
                data-ng-cloak>{{"These passwords don't match. Try again?"}}</div>

                <div class="error form-hint" data-ng-show="
                ( registerForm.confirm.$dirty && registerForm.confirm.$valid && !registerForm.confirm.$invalid) && 
                ( registerForm.password.$modelValue != registerForm.confirm.$modelValue )" data-ng-cloak>
                {{'Password mismatch'}}
                </div>

                <!-- Enter to Confirm password | Enter for Password confirmation -->
                <input type="text" class="form-control" id="confirmedID" name="confirm"
                placeholder="Password confirmation" 
                data-ng-required="true" data-ng-model="confirm77"
                data-ng-class="(registerForm.confirm.$dirty &&
                ( registerForm.confirm.$invalid || 
                ( registerForm.password.$modelValue != registerForm.confirm.$modelValue ) ) ) ? 'error' : ''" 
                data-compare-to="registerForm.password" >
            </div>
            <button id="siginButton" type="submit" class="btn" data-ng-disabled="registerForm.$invalid">Create an account</button>

        </form>
    </div>

  </div>
 </div>
</body>

脚本代码:

(function() {

  var loginModule = angular.module('loginModule', []);
  loginModule.constant('USERCONSTANTS', (function() {
    return {
        PASSWORD_LENGTH: 7
    }
  })());

  loginModule.controller('registerController', ['$scope','$http', '$window', '$location', registerControllerFun]);
  function registerControllerFun($scope, $http, $window, $location) {
    console.log(' registerControllerFun...');
  }
  loginModule.factory('myfactory', [function() {
    return {
        score: function() {
            //console.log('arguments List : ', arguments);
            var score = 0, value = arguments[0], passwordLength = arguments[1];
            var containsLetter = /[a-zA-Z]/.test(value), containsDigit = /\d/.test(value), containsSpecial = /[^a-zA-Z\d]/.test(value);
            var containsAll = containsLetter && containsDigit && containsSpecial;

            console.log(" containsLetter - ", containsLetter,
                    " : containsDigit - ", containsDigit,
                    " : containsSpecial - ", containsSpecial);

            if( value.length == 0 ) {
                score = 0;
            } else {
                if( containsAll ) {
                    score += 3;
                } else {
                    if( containsLetter ) score += 1;
                    if( containsDigit ) score += 1;
                    if( containsSpecial ) score += 1;
                }
                if(value.length >= passwordLength ) score += 1;
            }
            /*console.log('Factory Arguments : ', value, " « Score : ", score);*/
            return score;
        }
    };
  }]);

  loginModule.directive('okPasswordDirective', ['myfactory', 'USERCONSTANTS', function(myfactory, USERCONSTANTS) {
    return {
        restrict: 'AC',
        // use the NgModelController
        require: 'ngModel',

        // add the NgModelController as a dependency to your link function
        link: function($scope, $element, $attrs, ngPasswordModel) {
            console.log('Directive - USERCONSTANTS.PASSWORD_LENGTH : ', USERCONSTANTS.PASSWORD_LENGTH);

            $element.on('blur change keydown', function( evt ) {
                $scope.$evalAsync(function($scope) {
                    var pwd = $scope.password = $element.val();

                    $scope.myModulePasswordMeter = pwd ? (pwd.length > USERCONSTANTS.PASSWORD_LENGTH 
                            && myfactory.score(pwd, USERCONSTANTS.PASSWORD_LENGTH) || 0) : null;
                    ngPasswordModel.$setValidity('okPasswordController', $scope.myModulePasswordMeter > 3);
                });
                if( ngPasswordModel.$valid ) {
                    $scope.passwordVal = ngPasswordModel.$viewValue;
                    console.log('Updated Val : ', $scope.passwordVal);
                    $scope.updatePass();
                }
            });
        }
    };
  }]);

  loginModule.filter('passwordCountFilter', [ function() {
    var passwordLengthDefault = 7;
    return function( passwordModelVal ) {
        passwordModelVal = angular.isString(passwordModelVal) ? passwordModelVal : '';
        var retrunVal = passwordModelVal && 
            (passwordModelVal.length > passwordLengthDefault ? passwordLengthDefault + '+' : passwordModelVal.length);
        return retrunVal;
    };
  } ]);

  var compareTo = function() {
    return {
        require: "ngModel",
        // directive defines an isolate scope property (using the = mode) two-way data-binding
        scope: {
            passwordEleWatcher: "=compareTo"
        },

        link: function(scope, element, attributes, ngModel) {
            console.log('Confirm Password Link Function call.');

            var pswd = scope.passwordEleWatcher;

            ngModel.$validators.compareTo = function( compareTo_ModelValue ) {
                //console.log('scope:',scope);

                if( (pswd != 'undefined' && pswd.$$rawModelValue != 'undefined') && (pswd.$valid && pswd.$touched) ) {
                    var pswdModelValue = pswd.$modelValue;
                    var isVlauesEqual = ngModel.$viewValue == pswdModelValue;
                    return isVlauesEqual;
                } else {
                    console.log('Please enter valid password, before conforming the password.');
                    return false;
                }
            };

            scope.$watch("passwordEleWatcher", function() {
                console.log('$watch « Confirm-Password Element Watcher.')
                ngModel.$validate();
            });

            scope.$parent.updatePass = function() {
                console.log('$watch « Password Element Watcher.')
                console.log('Pswd: ',scope.$parent.passwordVal, '\t Cnfirm:', ngModel.$modelValue);
                //scope.registerForm.confirm.$invalid = true;
            }
        },
    };
  };
  loginModule.directive("compareTo", compareTo);
})(window.angular);

我们将不胜感激。

CSS classes观察:

ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required form-control ng-isolate-scope ng-invalid-compare-to
ng-pristine ng-touched ng-empty ng-invalid ng-invalid-required form-control ng-isolate-scope ng-invalid-compare-to

ng-dirty ng-valid-parse ng-touched ng-not-empty ng-invalid ng-valid-required error form-control ng-isolate-scope ng-invalid-compare-to
ng-dirty ng-valid-parse ng-touched ng-empty ng-invalid ng-valid-required error form-control ng-isolate-scope ng-invalid-compare-to

ng-dirty ng-valid-parse ng-touched ng-not-empty ng-valid ng-valid-required form-control ng-isolate-scope ng-valid-compare-to

我只想将 css 值从 ng-valid 更改为 ng-invalid

最佳答案

刚刚添加 expression [评估密码和确认密码的相等性] 到 ng-disabled - 按钮指令

代码 « Updated Fiddle

<button id="siginButton" type="submit" class="btn" data-ng-disabled="registerForm.$invalid">
Create an account
</button>

<!-- Changed to -->

<button id="siginButton" type="submit" class="btn"
    data-ng-disabled="registerForm.$invalid 
    || ( registerForm.confirm.$dirty && registerForm.confirm.$valid && !registerForm.confirm.$invalid )
    && ( registerForm.password.$modelValue != registerForm.confirm.$modelValue )">
Create an account
</button>

Confirm Password field with validation messages.

  • You can't leave this empty.
  • Confirm password with our Strong Password Policy.
  • These passwords don't match. Try again?

解决方案:

  1. 当密码字段无效时禁用 Conformation Password 字段。 Updated Fiddle

  2. 用户 ng-pattern attribute确认。 Updated Fiddle

Example :

<form name="registerForm" role="form" data-ng-submit="formSubmit()">
    Password:<input type="password" name="password" ng-model="password77">
    ConfirmPassword:<input type="password" name="confirm" ng-model="confirm77" ng-pattern="emailReg">

    <div class="error form-hint" ng-messages="registerForm.confirm.$error" data-ng-show="registerForm.confirm.$dirty">
        <p ng-show="registerForm.confirm.$error.required" ng-message="required">{{"You can't leave this empty."}}</p>
        <p ng-show="!(registerForm.confirm.$error.pattern && registerForm.confirm.$error.required) && registerForm.password.$invalid && !registerForm.confirm.$invalid" ng-message="pattern">{{"Confirm Password with our strong password policy!"}}</p>
        <p ng-show="registerForm.confirm.$invalid && !registerForm.confirm.$error.required && registerForm.confirm.$error.pattern" ng-message="">{{"These passwords don't match. Try again?"}}</p>
    </div>
</form>

关于javascript - AngularJS 确认密码验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44878725/

相关文章:

javascript - Angular 平移不区分大小写

javascript - XMLHttpRequest - event.loaded 和 event.total 值的问题

javascript - 为什么我应该选择在 AngularJS 中使用服务而不是工厂?

angularjs - 从 angularjs 工厂后端获取空模型并在成功后更新 Controller 变量

Javascript函数顺序

php - 制作画廊页面的最佳方式

html - CSS 文本叠加在完整图像上

css - Wordpress CSS 规则不适用于外部管理员登录

jQuery - 由于边距而无法单击 DOM 中的元素

javascript - ng-click、ng-mouseover 等是否会创建观察者并减慢页面速度?它比 jQuery 事件绑定(bind)更好吗?