Shlomi Atia
Shlomi Atia

Reputation: 105

Error: [$compile:multidir] when using multiple directives on same element

I made a form for credit cards payment which contain many validations, on the input below I try to validate 2 settings, one is the card type (visa,diners,amex, etc...) and the second validate is for the length of the card. I know there is a material design check for the length, but its not blocking the user from typing more than the specified number of characters.

Anyway, I'm getting this error:

Error: [$compile:multidir]

when using 2 directives on same input element

the element:

<input cc-type="ccType" wm-block wm-block-length="cardLength"/>

the ccType directive:

app.directive('ccType',[function(){
    return {
        restrict: 'A',
        scope:{
            ccType:'='
        },
        link: function (scope, elem, attr, ctrl) {
            elem.on('keyup',function(){
                var getCardType = function(cardNumber){
                    if(/^4[0-9]{6,}$/.test(cardNumber)){
                        return 'visa';
                    }
                    if(/^5[1-5][0-9]{5,}|222[1-9][0-9]{3,}|22[3-9][0-9]{4,}|2[3-6][0-9]{5,}|27[01][0-9]{4,}|2720[0-9]{3,}$/.test(cardNumber)){
                        return 'mastercard';
                    }
                    if(/^3[47][0-9]{5,}$/.test(cardNumber)){
                        return 'amex';
                    }
                    if(/^3(?:0[0-5]|[68][0-9])[0-9]{4,}$/.test(cardNumber)){
                        return 'diners';
                    }
                    if(/^6(?:011|5[0-9]{2})[0-9]{3,}$/.test(cardNumber)){
                        return 'discover';
                    }
                    if(/^(?:2131|1800|35[0-9]{3})[0-9]{3,}$/.test(cardNumber)){
                        return 'jcb';
                    }
                    return null;
                };
                scope.ccType = getCardType(ctrl.$modelValue);
            });
        }
    }
}]);

the wmBlock directive:

app.directive('wmBlock', function ($parse) {
    return {
        scope: {
          wmBlockLength: '='
        },
        link: function (scope, elm, attrs) {

          elm.bind('keypress', function(e){

            if(elm[0].value.length > scope.wmBlockLength){
              e.preventDefault();
              return false;
            }
          });
        }
    }   
});

Upvotes: 0

Views: 603

Answers (1)

jlast
jlast

Reputation: 391

Both wmBlock and ccType require a new isolated scope, which isn't allowed. To fix this, remove:

scope:{
   ccType:'='
},

and set the attribute directly:

attr.ccType = getCardType(ctrl.$modelValue);

Upvotes: 2

Related Questions