2017-07-03 150 views
0

在这里我面临的问题是关于低于指定的第三点(当用户更改密码值时)。AngularJS确认密码验证

  • 测试场景:
    1. 用户输入的所有领域正确 - [Button Enabled]
    2. 如果密码字段是无效的,因为它不符合密码强度那么create an account按钮处于禁用状态。
    3. 如果用户更改密码值但密码字段有效。 EX:[[email protected][email protected]] 此处确认字段值为[email protected]。那么按钮应该处于禁用模式。

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() function我没有收到最后通知的密码值。当我点击确认领域,它用来获得。 但没有用,我无法通过制作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-validng-invalid

+0

ngModel $ viewValue === pswdModelValue;这个小小的变化可能会给你提供解决方案,我认为需要严格的验证,使用“===”(类型安全的相等运算符)而不是“==”(常规对应) –

+0

抱歉,这里的问题不在于运营商。问题是iam无法获取updatePass()函数的更新值,我点击确认字段iam接收更新后的值。 – Yash

回答

0

只需添加expression [To evaluate equality of password and conformation password]对按钮的ng-disabled- Directive

代码«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> 

与验证消息确认密码字段。

  • 你不能把它留空。
  • 用我们的Strong Password Policy确认密码。
  • 这些密码不匹配。再试一次?

解决方案:

当密码字段无效
  1. 禁用构象密码字段。 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>