1

I want to build a validation directive for credit card expiry dates. One model has the month, the other has the year. Both model need to know the value of the other model in order to computer if the date is expired.

I got it working that the directive (it's called validExpiryDate) receives the models of the month and the year as parameters and then watches for changes in order to set the validity of the element.

However whenever I apply the valid-expiry-date on an input field the content of ng-model is not shown. The input field just stays blank.

This is the directive:

app.directive('validExpiryDate', function(Stripe) {
    return {
        restrict: 'A',
        require: 'ngModel',
        scope: {
            month: '=',
            year: '='
        },
        link: function(scope, elem, attrs, controller) {
            var state = function() { return  {month: scope.month, year: scope.year};};
            scope.$watch(state, function(v) {
                var isValid = Stripe.card.validateExpiry(scope.month, scope.year);
                controller.$setValidity('expiry-date', isValid);
            }, true);
        }
    };
});

And this is my current template code:

<input id="e1" type="text" ng-model="a" month="a" year="b" />
<input id="e2" type="text" ng-model="b" month="a" year="b" />
<input id="e3" type="text" ng-model="c" valid-expiry-date month="a" year="b" />
<!-- works, but doesnt show the input of ng-model c in e3  -->
<br />
<input id="e4" type="text" ng-model="a" valid-expiry-date month="a" year="b" />
<input id="e5" type="text" ng-model="b" valid-expiry-date month="a" year="b" />
<!-- e4 and e5 show the correct valid class, but do not the model -->

Any idea why the content is not displayed?

Edit

As Ajay pointed out the problem is the scope. Read more here: Directive with scope breaking ngmodel of an input

On this new insight I adjusted my model to this:

app.directive('validExpiryDate', function(Stripe) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attrs, controller) {
            var month = null;
            var year = null;

            var setValidity = function() {
                var isValid = Stripe.card.validateExpiry(month, year);
                controller.$setValidity('expiry-date', isValid);
            };

            scope.$watch(attrs.month, function(v) {
                month = v;
                setValidity()
            });

            scope.$watch(attrs.year, function(v) {
                year = v;
                setValidity()
            });
        }
    };
});

not really pretty but it works.

Community
  • 1
  • 1
  • you cannot use ngmodelcontroller with isolated scope – Ajay Beniwal Sep 19 '13 at 09:43
  • so how can i fix this? i need to have a ng-model and two bi-directional models (month and year). If you have (completely) other ways of doing this, I would love to hear about them. –  Sep 19 '13 at 09:51
  • I read more about the issue with several scopes here: http://stackoverflow.com/questions/16145571/directive-with-scope-breaking-ngmodel-of-an-input and made a change to the directive. The new version works, but doesn't look pretty. Somehow I couldn't watch both expressions. –  Sep 19 '13 at 10:57

0 Answers0