i have 2 input fields need validated after both fields have been entered. it's credit card expiration date, theres month , year. i'm using third-party service validation.
therefore, setup 3 directives: exp, expmonth, , expyear.
i use $watch validate user input - show error if validation false. when attempt ng-class exampleform.$error.expiry, error: [$rootscope:infdig] 10 $digest() iterations reached.
here demo http://plnkr.co/edit/ssisflb8heeb4mrdgaoo?p=preview
view.html
<form name='exampleform' novalidate> <div class="form-group" ng-class="{ 'is-invalid': exampleform.$error.expiry }"> <div class="expiration-wrapper" exp> <input type='text' ng-model='data.year' name='year' exp-month /> <input type='text' ng-model='data.month' name='month' exp-year /> </div> </div> exp.directive.js
angular.module('example') .directive('exp', ['thirdpartyvalidationservice', function(thirdpartyvalidationservice) { return { restrict: 'a', require: 'exp', link: function(scope, element, attrs, ctrl) { ctrl.watch(); }, controller: function($scope, $element, thirdpartyvalidationservice) { var self = this; var parentform = $element.inheriteddata('$formcontroller'); var ngmodel = { year: {}, month: {} }; var setvalidity = function(exp) { var expmonth = exp.month; var expyear = exp.year; var valid = thirdpartyvalidationservice.validateexpiry(expmonth, expyear); parentform.$setvalidity('expiry', valid, $element); }; self.setmonth(monthctrl) { ngmodel.month = monthctrl; }; self.setyear(yearctrl) { ngmodel.year = yearctrl; }; self.watch = function() { $scope.$watch(function() { return { month: ngmodel.month.$modelvalue, year: ngmodel.year.$modelvalue }; }, setvalidity, true); }; } }; }]); expmonth.directive.js
angular.module('example') .directive('expmonth', [ function() { return { restrict: 'a', require: ['ngmodel', '^?exp'], compile: function(element, attributes) { return function(scope, element, attributes, controllers) { var formctrl = controllers[0]; var expmonthctrl = controllers[1]; expmonthctrl.setmonth(formctrl); }; }; }; }]); expyear.directive.js
angular.module('example') .directive('expyear', [ function() { return { restrict: 'a', require: ['ngmodel', '^?exp'], compile: function(element, attributes) { return function(scope, element, attributes, controllers) { var formctrl = controllers[0]; var expyearctrl = controllers[1]; expyearctrl.setyear(formctrl); }; }; }; }]);
the problem setting validity error jquery selection line:
parentform.$setvalidity('expiry', valid, $element); then watching jquery element via ng-class when have:
ng-class="{ 'is-invalid' : exampleform.$error.expiry }" in markup. causes strange exceptions thrown when angular tries deep copy value.
instead, change use .length property of jquery object instead. if non-zero (truthy), is-invalid class set correctly, otherwise won't be.
ng-class="{ 'is-invalid' : exampleform.$error.expiry.length }" you ...expiry.length > 0 if makes more sense , future developers have @ code.
i forked plunkr works change.
Comments
Post a Comment