директива перевірки пароля в angularjs


76

Я пишу директиву про перевірку пароля:

 Directives.directive("passwordVerify",function(){
    return {
        require:"ngModel",
        link: function(scope,element,attrs,ctrl){
            ctrl.$parsers.unshift(function(viewValue){
                var origin = scope.$eval(attrs["passwordVerify"]);
                if(origin!==viewValue){
                    ctrl.$setValidity("passwordVerify",false);
                    return undefined;
                }else{
                    ctrl.$setValidity("passwordVerify",true);
                    return viewValue;
                }
            });

        }
    };
});

html:

<input data-ng-model='user.password' type="password" name='password' placeholder='password' required>
<input data-ng-model='user.password_verify' type="password" name='confirm_password' placeholder='confirm password' required data-password-verify="user.password">

Дано 2 поля пароля у формі, якщо обидва значення пароля рівні, тоді поле, на яке впливає директива, є дійсним. Проблема в тому, що це працює в один бік (тобто, коли я вводжу пароль у полі перевірки пароля). Однак, коли оригінальне поле пароля оновлено, перевірка пароля стає недійсною.

Будь-яка ідея, як я можу мати "двосторонню перевірку прив'язки?"

Відповіді:


60

Це має вирішити:

Вид:

<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>

Директива

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;
                    }
                });
            }
        });
     }
   };
});

1
Я використав фрагмент перевірки у документі, дозвольте мені спробувати ваш код.
mpm

Я змінив свою відповідь. Це має спрацювати. Дивіться jsFiddle
asgoth

Це все ще не дає двосторонніх прив’язок, або щось змінилося з тих пір?
Хадесара

1
Я згоден з CWSpear. Рішення слід виправити помилкою, коментованою вище
gyss

9
З цим рішенням відбувається витік пам’яті. Кожна подія перегляду, яка запускається натисканням іншого синтаксичного аналізатора на масив парсерів ctrl. $. Перевірка ctrl. $ Parsers.length у кінці обробника події годинника це покаже.
mshiltonj

114

Я використовую наступну директиву, оскільки хочу повторно перевірити обидва поля введення, незалежно від того, чи було змінено значення 1 або значення 2:

директива:

'use strict';

angular.module('myApp').directive('equals', 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('equals', function (val) {
        validate();
      });

      var validate = function() {
        // values
        var val1 = ngModel.$viewValue;
        var val2 = attrs.equals;

        // set validity
        ngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2);
      };
    }
  }
});

використання

<input type="password" ng-model="value1" equals="{{value2}}" required>
<input type="password" ng-model="value2" equals="{{value1}}" required>

4
Я виявив, що це працює досить добре. Одне, що мене зачепило, це те, що якщо у вас є інший кутовий валідатор, наприклад: ng-minlengthна першому полі, то ця модель не встановлюється, доки вона насправді не буде дійсною
Intellix,

5
Я завернув ngModel.$setValidityз if (val1 && val2) { .. }тільки тому форма не діє , якщо обидва значення порожні.
jesal

4
Це має деякі невеликі проблеми, коли в грі більше правил перевірки. Якщо інша перевірка не вдається, Angular не оновлює модель, і у порівнянні трапляються дивні речі ...
user2173353

7
Для мене це чудово працювало. Як новачкові, це допомогло б додати до цього рядок перевірки. [form name].[field name].$error.equalsВикористовуйте це для контролю того, які поля повинні чи повинні відображатися. Я використовую його для міток помилок.
metric152

3
Я думаю, що краще замінити ngModel.$setValidity('equals', val1 === val2);наngModel.$setValidity('equals', ! val1 || ! val2 || val1 === val2);
bullgare

85

Створення окремої директиви для цього не потрібно. Інструмент перевірки пароля Angular UI вже побудований . За допомогою цього ви могли зробити:

<input name="password" required ng-model="password">
<input name="confirm_password"
       ui-validate=" '$value==password' "
       ui-validate-watch=" 'password' ">

 Passwords match? {{!!form.confirm_password.$error.validator}}

3
для якого зараз потрібен jQuery
Intellix

24
@DominicWatson За що ви мене голосуєте? Це питання стосується кутового, і я маю на увазі кутові документи. Піди вчитися, якщо ти не розумієш різниці між ними.
велосипед

24
@DominicWatson Директива тут github.com/angular-ui/ui-utils/blob/master/modules/validate/…, за винятком jquery lite, в ньому немає ніякого дивного jquery. Якщо ви настільки анти jquery, ви все одно не повинні використовувати цей фреймворк, оскільки він включає jquery.
велосипед

3
У мене така ж проблема, як і в оригінальному дописі. Якщо в angular-ui є щось вже вбудоване, чи не має сенсу використовувати це замість того, щоб повторно винаходити колесо?
PeterG 03.03.14

2
@PeterG Я не думаю, що Домінік Ватсон мав уявлення, про що він говорив
велосипед

22

Ще одне рішення щодо цього полягає у відповідності моделі одного входу до значення іншого входу.

app.directive('nxEqual', function() {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, model) {
            if (!attrs.nxEqual) {
                console.error('nxEqual expects a model as an argument!');
                return;
            }
            scope.$watch(attrs.nxEqual, function (value) {
                model.$setValidity('nxEqual', value === model.$viewValue);
            });
            model.$parsers.push(function (value) {
                var isValid = value === scope.$eval(attrs.nxEqual);
                model.$setValidity('nxEqual', isValid);
                return isValid ? value : undefined;
            });
        }
    };
});

Отже, якщо модель вікна пароля така, login.passwordтоді ви встановлюєте наступний атрибут у полі перевірки: nx-equal="login.password"і тестуєте на formName.elemName.$error.nxEqual. Подобається так:

<form name="form">
    <input type="password" ng-model="login.password">
    <input type="password" ng-model="login.verify" nx-equal="login.password" name="verify">
    <span ng-show="form.verify.$error.nxEqual">Must be equal!</span>
</form>

Розширена версія:

Для нового мого проекту мені довелося змінити вищевказану директиву, щоб вона відображала nxEqualпомилку лише тоді, і лише тоді, коли вхід для перевірки мав значення. В іншому випадку nxEqualпомилку слід вимкнути. Ось розширена версія:

app.directive('nxEqualEx', function() {
    return {
        require: 'ngModel',
        link: function (scope, elem, attrs, model) {
            if (!attrs.nxEqualEx) {
                console.error('nxEqualEx expects a model as an argument!');
                return;
            }
            scope.$watch(attrs.nxEqualEx, function (value) {
                // Only compare values if the second ctrl has a value.
                if (model.$viewValue !== undefined && model.$viewValue !== '') {
                    model.$setValidity('nxEqualEx', value === model.$viewValue);
                }
            });
            model.$parsers.push(function (value) {
                // Mute the nxEqual error if the second ctrl is empty.
                if (value === undefined || value === '') {
                    model.$setValidity('nxEqualEx', true);
                    return value;
                }
                var isValid = value === scope.$eval(attrs.nxEqualEx);
                model.$setValidity('nxEqualEx', isValid);
                return isValid ? value : undefined;
            });
        }
    };
});

І ви б використали це так:

<form name="form">
    <input type="password" ng-model="login.password">
    <input type="password" ng-model="login.verify" nx-equal-ex="login.password" name="verify">
    <span ng-show="form.verify.$error.nxEqualEx">Must be equal!</span>
</form>

Спробуйте: http://jsfiddle.net/gUSZS/


3
Цей найкращий. Це найкоротше. Це працює на модельних значеннях і працює в обох напрямках.
CMCDragonkai

Однак одне - це те, що конвеєр $ parser повинен повертати значення або невизначене. Таким чином подальші труби не просто закінчуються, тому що вони завжди повертаються невизначеними, коли немає функції повернення. Також область дії повинна бути помилковою.
CMCDragonkai

@CMCDragonkai: Хороший улов! Я оновив повертане значення функції-аналізатора. Щодо сфери, наскільки мені відомо, вона за замовчуванням false, тому, не чітко вказуючи область, якій вона дорівнює scope: false.
Фредрік

Я думаю, що це фактично за замовчуванням справді бути дітьми. Але я не перевіряв нещодавно.
CMCDragonkai

1
@GillBates Використання ізольованої області дії та прив'язка аргументу =не переглядає перший ввід після його заповнення. Я зробив швидкий JSFiddle, який відображає цю проблему.
Фредрік

14

Я зробив це без директиви.

<input type="password" ng-model="user.password" name="uPassword" required placeholder='Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
    <span class="error" ng-show="form.uPassword.$dirty && form.uPassword.$error.minlength">Too short</span>
    <span ng-show="form.uPassword.$dirty && form.uPassword.$error.required">Password required.</span><br />

    <input type="password" ng-model="user.confirmpassword" name="ucPassword" required placeholder='Confirm Password' ng-minlength="3" ng-maxlength="15" title="3 to 15 characters" />
    <span class="error" ng-show="form.ucPassword.$dirty && form.ucPassword.$error.minlength">Too short</span>
    <span ng-show="form.ucPassword.$dirty && form.ucPassword.$error.required">Retype password.</span>
    <div ng-show="(form.uPassword.$dirty && form.ucPassword.$dirty) && (user.password != user.confirmpassword)">
        <span>Password mismatched</span>
    </div>

4
Ви повинні використовувати директиву, як уже зазначалося, форма залишається в дійсному стані. В іншому випадку ви могли б також зробити для нього якийсь прослуховувач jquery.
велосипед


8

Починаючи з кутової версії 1.3.0-beta12, недійсні вхідні дані не записують у ngModel, тому ви не можете переглядати І ПОТІМ перевіряти, як ви можете бачити тут: http://plnkr.co/edit/W6AFHF308nyKVMQ9vomw?p=preview . Було запроваджено новий конвеєр валідаторів, і ви можете приєднатись до нього, щоб досягти того самого.

Власне, у цій примітці я створив компонент bower для загальних додаткових валідаторів: https://github.com/intellix/angular-validators, який включає це.

angular.module('validators').directive('equals', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, elem, attrs, ngModel)
        {
            if (!ngModel) return;

            attrs.$observe('equals', function() {
                ngModel.$validate();
            });

            ngModel.$validators.equals = function(value) {
                return value === attrs.equals;
            };
        }
    };
});

angular.module('validators').directive('notEquals', function() {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function(scope, elem, attrs, ngModel)
        {
            if (!ngModel) return;

            attrs.$observe('notEquals', function() {
                ngModel.$validate();
            });

            ngModel.$validators.notEquals = function(value) {
                return value === attrs.notEquals;
            };
        }
    };
});

найкраще рішення на сьогоднішній день
Ратма

7

Я вже успішно використовував цю директиву:

 .directive('sameAs', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (viewValue === scope[attrs.sameAs]) {
          ctrl.$setValidity('sameAs', true);
          return viewValue;
        } else {
          ctrl.$setValidity('sameAs', false);
          return undefined;
        }
      });
    }
  };
});

Використання

     <input ... name="password" />
    <input type="password" placeholder="Confirm Password" 
name="password2" ng-model="password2" ng-minlength="9" same-as='password' required>

Мені найбільше подобається це рішення - не обмежує його збігом паролів
Shaz,

7

Я мав справу з тим самим питанням і знайшов хороший допис у блозі про нього, написаний Петром Будою. Це хороше читання, і воно дуже добре пояснює процес. Код такий:

directives.directive("repeatPassword", function() {
    return {
        require: "ngModel",
        link: function(scope, elem, attrs, ctrl) {
            var otherInput = elem.inheritedData("$formController")[attrs.repeatPassword];

            ctrl.$parsers.push(function(value) {
                if(value === otherInput.$viewValue) {
                    ctrl.$setValidity("repeat", true);
                    return value;
                }
                ctrl.$setValidity("repeat", false);
            });

            otherInput.$parsers.push(function(value) {
                ctrl.$setValidity("repeat", value === ctrl.$viewValue);
                return value;
            });
        }
    };
});

Тож ви можете зробити щось на зразок:

<input type="password" name="repeatPassword" id="repeatPassword" placeholder="repeat password" ng-model="user.repeatPassword" repeat-password="password" required>

Почесна заслуга автора


Після жахливої ​​гарячки, це було для мене найкращим рішенням при використанні додаткових атрибутів перевірки (наприклад, мінімальна довжина, необхідна тощо)
Carlos P

3

Це недостатньо добре:

<input type="password" ng-model="passwd1" />
<input type="password" ng-model="passwd2" />
<label ng-show="passwd1 != passwd2">Passwords do not match...</label>
<button ng-disabled="passwd1 != passwd2">Save</button>

Просто, і для мене дуже добре працює.


1
Це не перевірка. форма. $ valid буде рівним true.
Intellix

Ми могли вимкнути кнопку Зберегти, доки не буде виконано умову пароля (додано те саме вище).
Джаспер

Це все ще не належне підтвердження. Існує ціла система перевірки, не використовувати її для збереження кількох рядків просто безглуздо.
DennisK

Денніс Кр0гер> Це чудово працює .. Не могли б ви вказати, що з цим не так?
Джаспер

3

Це рішення схоже на рішення Домініка Ватсона, який використовує валідатори $ і є тим, що мені найбільше подобається. Єдині зміни полягають у тому, що ви можете переглядати вираз.

$ validators Колекція валідаторів, що застосовуються при зміні значення моделі. Значення ключа в об'єкті посилається на ім'я валідатора, тоді як функція посилається на операцію перевірки. Операція перевірки надається зі значенням моделі як аргумент і повинна повертати істинне або хибне значення залежно від відповіді цієї перевірки

від https://code.angularjs.org/1.3.15/docs/api/ng/type/ngModel.NgModelController

Я використовую angular 1.3. Моя директива виглядає приблизно так

angular.module('app').directive("passwordConfirm", function() {
    "use strict";
    return {
        require : "ngModel",
        restrict : "A",
        scope : {
            //We will be checking that our input is equals to this expression
            passwordConfirm : '&'
        },
        link : function(scope, element, attrs, ctrl) {
            //The actual validation
            function passwordConfirmValidator(modelValue, viewValue) {
                return modelValue == scope.passwordConfirm();
            }
            //Register the validaton when this input changes
            ctrl.$validators.passwordConfirm = passwordConfirmValidator;
            //Also validate when the expression changes
            scope.$watch(scope.passwordConfirm, ctrl.$validate);
        }
    };
});

Щоб використовувати його

<input type="password" ng-model="user.password"/>
<input type="password" ng-model="user.confirmPassword" 
                password-confirm="user.password" />

3

Для перевірки форми з двома полями введення я знаходжу найбільш підходящий спосіб

Директива

app.directive('passwordVerify', function() {
return {
    require: 'ngModel',
    link: function (scope, elem, attrs, ctrl) {
        if (!attrs.passwordVerify) {
            return;
        }
        scope.$watch(attrs.passwordVerify, function (value) {
          if( value === ctrl.$viewValue && value !== undefined) {
             ctrl.$setValidity('passwordVerify', true);
             ctrl.$setValidity("parse",undefined);
          }
          else {
             ctrl.$setValidity('passwordVerify', false);
          }
        });
        ctrl.$parsers.push(function (value) {
            var isValid = value === scope.$eval(attrs.passwordVerify);
            ctrl.$setValidity('passwordVerify', isValid);
            return isValid ? value : undefined;
        });
    }
  };
});

HTML

     <div class="row">
        <div class="col-md-10 col-md-offset-1">
          <div class="form-group" ng-class="{ 'has-error': form.password.$dirty && form.password.$error.required || (form.password.$error.minlength || form.password.$error.maxlength)}">
              <input type="password" name="password" ng-minlength="6" ng-maxlength="16" id="password" class="form-control" placeholder="Password" ng-model="user.password" required />
              <span ng-show="form.password.$dirty && form.password.$error.required" class="help-block">Password is required</span>
              <span ng-show="form.password.$error.minlength || form.password.$error.maxlength" class="help-block">Password must be 6-16 character long</span>
          </div>
        </div>
       </div>
       <div class="row">
         <div class="col-md-10 col-md-offset-1">
           <div class="form-group" ng-class="{ 'has-error': (form.confirm_password.$dirty && form.confirm_password.$error.required) || form.confirm_password.$error.passwordVerify }">
              <input type="password" name="confirm_password" id="confirm_password" class="form-control" placeholder="Confirm Password" ng-model="user.confirm_password" required password-verify="user.password" />
              <span ng-show="form.confirm_password.$dirty && form.confirm_password.$error.required" class="help-block">Confirm Password is required</span>
              <span ng-show="form.confirm_password.$error.passwordVerify" class="help-block">Please make sure passwords match & must be 6-16 character long</span>
          </div>
        </div>
      </div>

2

Це працює в обох напрямках, і це просто і чисто

JavaScript

var app = angular.module("app");

app.controller("SamePaswordController", function () {

  this.password;
  this.confirm;

  this.save = function () {
    alert("Saved!");
  };
}


app.directive("match", function () {
  return {
    restrict:"A",
    require:"ngModel",

    link: function(scope, element, attrs, ctrl) {

      function matchValidator(value) {      

        scope.$watch(attrs.match, function(newValue, oldValue) {

          var isValid = value === scope.$eval(attrs.match);                    
          ctrl.$setValidity('match', isValid);

        });

        return value;
      }

      ctrl.$parsers.push(matchValidator);
    }
  };
});

HTML: зверніть увагу на директиву збігів

<form name="regForm" ng-controller="SamePaswordController as regCtrl"
      ng-submit="regForm.$valid && regCtrl.save()" novalidate>

  <input name="password" ng-model="regCtrl.password" 
         type="password" required placeholder="Password"/>                

  <input name="confirm" ng-model="regCtrl.confirm" match="regCtrl.password"
         type="password" required placeholder="Confirm password"/>


  <div> regForm is valid:{{regForm.$valid}}</div>

  <input type="submit" value="Save"/>

</form>

Ви можете клонувати репо за допомогою цього прикладу https://github.com/rogithub/roangularjs


Приємними частинами є: scope. $ Watch, scope. $ Eval and match = "regCtrl.password".
Ро.

У мене це не спрацювало. Переглядає підтвердження змін і приклад, який я вважаю неправильним. match = {{regCtrl.password "}}
Енкоде

2

Не директивне рішення, але працює для мене:

<input ng-model='user.password'
 type="password"
 name='password'
 placeholder='password'
 required>
<input ng-model='user.password_verify'
 type="password" 
 name='confirm_password'
 placeholder='confirm password'
 ng-pattern="getPattern()"
 required>

А в контролері:

//Escape the special chars
    $scope.getPattern = function(){
        return $scope.user.password && 
              $scope.user.password.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1');
    }

http://plnkr.co/edit/QDTnipCsHdg56vgygsqC?p=preview


1

Далі подано мій погляд на проблему. Ця директива буде порівнювати зі значенням форми замість області.

'use strict';
(function () {
    angular.module('....').directive('equals', function ($timeout) {
        return {
            restrict: 'A',
            require: ['^form', 'ngModel'],
            scope: false,
            link: function ($scope, elem, attrs, controllers) {
                var validationKey = 'equals';
                var form = controllers[0];
                var ngModel = controllers[1];

                if (!ngModel) {
                    return;
                }

                //run after view has rendered
                $timeout(function(){
                    $scope.$watch(attrs.ngModel, validate);

                    $scope.$watch(form[attrs.equals], validate);
                }, 0);

                var validate = function () {
                    var value1 = ngModel.$viewValue;
                    var value2 = form[attrs.equals].$viewValue;
                    var validity = !value1 || !value2 || value1 === value2;
                    ngModel.$setValidity(validationKey, validity);
                    form[attrs.equals].$setValidity(validationKey,validity);
                };
            }
        };
    });
})();

в HTML тепер одне посилається на фактичну форму замість значення масштабу:

<form name="myForm">
  <input type="text" name="value1" equals="value2">
  <input type="text" name="value2" equals="value1">
  <div ng-show="myForm.$invalid">The form is invalid!</div>
</form>

Не схоже, що значення форми можна спостерігати, тому я думаю, що $scope.$watch(form[attrs.equals], validate);насправді це ніколи не викликається. В іншому випадку було б достатньо просто мати equalsатрибут лише на одному елементі.
Вадим

0

Для того, щоб досягти перевірки при зміні обох входів, я використовую такий код (який був поєднанням всіх інших відповідей):

angular.module('app.directives')
.directive('passwordVerify', [function () {
    return {
        require: '?ngModel',
        restrict: 'A',
        scope: {
            origin: '=passwordVerify'
        },
        link: function (scope, element, attrs, ctrl) {
            if(!ctrl) {
                return;
            }

            function validate(value) {
                ctrl.$setValidity('passwordMatch', scope.origin === value);
                return value;
            }

            ctrl.$parsers.unshift(validate);

            scope.$watch('origin', function(value) {
                validate(ctrl.$viewValue);
            });
        }
    };
}]);

0

По-перше, я хотів би подякувати Фредріку за розміщення цього чудового прикладу. Є одна крихітна проблема, з якою я зіткнувся випадково. на скрипці, яку ви розмістили http://jsfiddle.net/gUSZS/

Якщо ви введете пароль, а потім введете той самий пароль в елементі введення для перевірки, все працює нормально, але спробуйте додати пробіл до другого вікна, і angular автоматично обріже цей простір. Це означає, що директива не "бачить" зайвий простір. Зараз паролі різні, але форма все ще діє.

щоб це виправити, нам потрібно додати

ng-trim="false"

до вхідних елементів. Це не працює в angular 1.0.3, тому, якщо ви хочете спробувати його в цій скрипці, вам потрібно додати 1.1.1 до скрипки ( http://ajax.googleapis.com/ajax/libs/angularjs/1.1.1/angular .js )

Але знову ж таки, дякую Фредеріку, я буду використовувати ваше рішення у своєму додатку!

Антон П.С. Я хотів прокоментувати пост Фредеріка, але я новачок на цьому форумі і, здається, не маю достатньо кредитів. Тож було б дуже вдячно, якщо хтось із вас може проголосувати за мій коментар, якщо він вам подобається :-)


0

Не потрібно додаткової директиви, ось мій погляд на це:

HTML:

<div class="form-group" data-ng-class="{ 'has-error': submitted && !form.new_passwd.$valid }">
    <input type="password" name="new_passwd" class="form-control" data-ng-model="data.new_passwd" placeholder="New Password" required data-ng-pattern="passwdRegex">
    <small class="help-block" data-ng-show="submitted && form.new_passwd.$error.required">New password is required!</small>
    <small class="help-block" data-ng-show="submitted && !form.new_passwd.$error.required && form.new_passwd.$error.pattern">New password is not strong enough!</small>
</div>

<div class="form-group" data-ng-class="{ 'has-error': submitted && !form.new_passwd_conf.$valid }">
    <input type="password" name="new_passwd_conf" class="form-control" data-ng-model="data.new_passwd_conf" placeholder="Confirm New Password" required data-ng-pattern="passwdConfRegex">
    <small class="help-block" data-ng-show="submitted && form.new_passwd_conf.$error.required">New password confirmation is required!</small>
    <small class="help-block" data-ng-show="submitted && !form.new_passwd_conf.$error.required && form.new_passwd_conf.$error.pattern">New password confirmation does not match!</small>
</div>

Javascript:

$scope.passwdRegex = /^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[^\da-zA-Z]).{8,}$/;
$scope.$watch('data.new_passwd', function() {
    $scope.passwdConfRegex = new RegExp(Regex.escape($scope.data.new_passwd));
});

де Regex.escape () можна знайти тут .

Працює як оберіг!


я спробував з jsfiddle не працює, ви можете зібрати і показати нам?
Нік Кан,

0

Якщо додати до великої кількості вже існуючих рішень, це мені добре підходить.

(Відповідь Яна Лауссмана перестала працювати з останніми бета-версіями AngularJS).

директива:

angular.module('myApp').directive('matchValidator', [function() {
        return {
            require: 'ngModel',
            link: function(scope, elm, attr, ctrl) {
                var pwdWidget = elm.inheritedData('$formController')[attr.matchValidator];

                ctrl.$parsers.push(function(value) {
                    if (value === pwdWidget.$viewValue) {
                        ctrl.$setValidity('match', true); 
                        return value;
                    }                       

                    if (value && pwdWidget.$viewValue) {
                        ctrl.$setValidity('match', false);
                    }

                });

                pwdWidget.$parsers.push(function(value) {
                    if (value && ctrl.$viewValue) {
                        ctrl.$setValidity('match', value === ctrl.$viewValue);
                    }
                    return value;
                });
            }
        };
    }])

використання

<input type="email" ng-model="value1" name="email" required>
<input type="email" ng-model="value2" name="emailConfirm" match-validator="email" required>

помилка відображення

<div ng-if="[[yourFormName]].emailConfirm.$error">
    <div ng-if="[[yourFormName]].emailConfirm.$error.match">
        Email addresses don't match.
    </div>
</div>

0
   <input name="password" type="text" required="" ng-model="password" placeholder="password" class="ng-dirty ng-valid ng-valid-required">
   <input name="confirm_password" type="text" required="" ng-model="confirm_password" ui-validate=" '$value==password' " ui-validate-watch=" 'password' " placeholder="confirm password" class="ng-dirty ng-valid-required ng-invalid ng-invalid-validator"> 
   <span ng-show="form.confirm_password.$error.validator">Passwords do not match!</span>
        password errors: {
        "required": false,
        "validator": true
        }

0

Це спрацювало для мене.

Директива:

modulename.directive('passwordCheck', 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

            var Value = null;

            // watch own value and re-validate on change
            scope.$watch(attrs.ngModel, function (val) {
                Value = val;


                validate();
            });

            // observe the other value and re-validate on change
            attrs.$observe('passwordCheck', function () {
                validate();
            });

            var validate = function () {

                // values
                var val1 = Value;
                var val2 = attrs.passwordCheck;

                // set validity

                if (val1 != '' && val1 != undefined) {
                    ngModel.$setValidity('passwordCheck', val1 == val2);

                }

                else {
                    ngModel.$setValidity('passwordCheck', true);
                }
            };
        }
    }
});

HTML:

ng-model="confirmpassword.selected" type="password" name="confirmpassword" 

password-check="{{password.selected}}"

ng-show="resetpasswordform.confirmpassword.$error.passwordCheck && submitted" Password does not match

0

У мене була та сама проблема, коли я намагався створити власну директиву, і я виправив це за допомогою цього доповнення

ctrl.$validate();

де ctrl - це мій ngModelController

це мій погляд

<input type="password" match="signupCtrl.registrationData.password" name="confirmPassword" class="form-control" placeholder="Confirm Password" data-ng-model="signupCtrl.registrationData.confirmPassword" required>
        <span ng-messages="registerForm.confirmPassword.$error">
            <span ng-message="match">The Password must match</span>
        </span>

це моя директива

(function () {
    'use strict';
    angular.module('matchDirective', [
        // Angular modules
        // Custom modules
        // 3rd Party Modules
    ]);
})(); 
(function () {
    'use strict';
    angular
        .module('matchDirective')
        .directive('match', match);
    match.$inject = ['$window'];

    function match($window) {
        // Usage:
        //     <element match="source"></element>
        // Creates:
        //
        var directive = {
            link: link,
            restrict: 'A',
            require: 'ngModel',
        };
        return directive;

        function link(scope, element, attrs, ctrl) {
            scope.$watch(attrs['match'], function (newVal, oldVal) {
                ctrl.$validators.match = function (modelValue, viewValue) {
                    if (newVal == modelValue) {
                        return true;
                    } else {
                        return false;
                    }
                }
                ctrl.$validate();
            });
        }
    }
})();

0

Щось подібне працює для мене:

js:

.directive('sameAs', function() { return {
    require : 'ngModel',
    link : function(scope, elm, attrs, ngModelCtrl) {

        ngModelCtrl.$validators.sameAs = function(modelValue, viewValue) {
            var checkedVal = attrs.sameAs;
            var thisInputVal = viewValue;

            if (thisInputVal == checkedVal) {
                return true; // valid
            } else {
                return false;
            }
        };
    }
}; });

html:

<input type="password" name="password" id="password" ng-model="password" />

<input type="password" name="passwordRepeat" id="passwordRepeat" 
    ng-model="passwordRepeat" same-as="{{password}}" />

0

Принцип «Тримай його простим і дурним» (KISS) може бути корисним для цього. Швидше і простіше перевірити, чи збігаються обидва паролі, виконавши наступне:

<div ng-app="app" ng-controller="passwordCheck">
  <form name="signUp" ng-submit="submitForm()" novalidate>
     <input type="password" name="password" ng-model="password" required>
     <input type="password" name="ConfirmPassword" ng-model="passwordconfirm"   required>
     <button type="submit"> Submit</button>
  </form>

  <hr>
  <span>Do they match?</span> {{signUp.password.$viewValue == signUp.confirmPassword.$viewValue}}
    </div>

І перед тим, як подавати форму, ви можете зробити це у своєму js

var app = angular.module("app", []);
app.controller("passwordCheck", function($scope) {
   $scope.submitForm = function() {
      if ($scope.signUp.$valid && $scope.signUp.password.$viewValue == $scope.signUp.confirmPassword.$viewValue) {
            alert('Its a match!');
        };
};
});

Ви можете протестувати це також у JSfiddle .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.