Search code examples
javascriptangularjsangularjs-directiveextendingangular-template

Extending a 3rd party angular directive and changing its template


I'm using Daniel Crisps AngularJS Range Slider https://github.com/danielcrisp/angular-rangeslider and would like to extend his directive and modify the template.

His directive looks something like this (shortened for space):

angular.module('ui-rangeSlider', [])
.directive('rangeSlider', [
    function () {
       return {
          restrict: 'A',
          replace: true,
          template: ['<div class="ngrs-range-slider">',
                         '<div class="ngrs-runner">',
                           '<div class="ngrs-handle ngrs-handle-min"><i></i></div>',
                           '<div class="ngrs-handle ngrs-handle-max"><i></i></div>',
                           '<div class="ngrs-join"></div>',
                         '</div>',
                         '<div class="ngrs-value-runner">',
                           '<div class="ngrs-value ngrs-value-min" ng-show="showValues"><div>{{filteredModelMin}}</div></div>',
                           '<div class="ngrs-value ngrs-value-max" ng-show="showValues"><div>{{filteredModelMax}}</div></div>',
                         '</div>',
                       '</div>'].join('')
       }
    }
]);

I've been trying to use the suggestion in this question Extending Angular Directive by naming my directive the exact same name (shortened for example):

angular.module('myDirective', [])
.directive('rangeSlider', [
    function () {
        return {
            restrict: 'A',
            priority: 500,
            template: ['<div></div><div></div>'].join('')
        }
    }
]);

But am getting the following error: Multiple directives [rangeSlider, rangeSlider] asking for template on:

Has anyone run into this before and how would I go about updating the original template without modifying it in its source?

Edit: Had a an extra ')' in my example.


Solution

  • After a bunch of stackoverflow searching on how to extend AngularJS Directives (preferably in version 1.5.*), this is what worked for me.

    Slightly modifying the decorator and $delegate from the above examples to work with Angular 1.5.8:

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
    
    <script>
            angular.module('ui-rangeSlider', []).directive('rangeSlider', [function() {
            return {
                restrict: 'A',
                replace: true,
                template: ['<div>base</div>'].join('')
            };
        }]);
        angular.module('myDirective', []).directive('rangeSlider', [function() {
            return {
                restrict: 'A',
                priority: 500,
                template: ['<div>extended</div>'].join('')
            }
        }]);
        angular.module('sample', ['ui-rangeSlider', 'myDirective'])
            .decorator('rangeSliderDirective', ['$delegate', function($delegate){
                console.log($delegate);
              $delegate.shift();
              return $delegate;
            }]);
    </script>
    
    <body ng-app="sample">
        <div range-slider></div>
    </body>
    

    You can see the above code working here:
    https://jsfiddle.net/sjxwLe4k/6/