arjun
arjun

Reputation: 560

How to change the css class of a element inside a directive?

I want to change the color of the icon respect to the button clicked by the user ( say there is a popover which has three buttons namely high,medium , low . if a user clicks "high" it should changes to red color. medium - orange.. low - blue.. I made a directive for popover with three buttons. but i am unable to update the css classes with respect to the button click.

html:

 <span class="tk-action-s">
 <i priority-over class="fa fa-star {{colorChanger}}" ng-class="colorChanger"></i>
 </span>

directive :

myApplication.directive('priorityOver', function ($compile) {

    var itemsTemplate = "<div class=\"btn-group\"></div><div class=\"btn-group\"><label class=\"btn btn-danger\" ng-model=\"priority\" btn-radio=\"'high'\" ng-click=\"changeColor()\" uncheckable>High</label><label class=\"btn btn-warning\" ng-model=\"priority\" btn-radio=\"'medium'\" uncheckable>Medium</label><label class=\"btn btn-primary\" ng-model=\"priority\" btn-radio=\"'low'\" uncheckable>Low</label></div>";
    var getTemplate = function () {
        var template = '';
        template = itemsTemplate;
        return template;
    }
    return {
        restrict: "AC",
        transclude: true,
        template: "<span ng-transclude></span>",
        controller: function($scope, $element, $attrs) {
        $scope.colorChanger = 'col';
     },
        link: function (scope, element, attrs) {
            scope.colorChanger = 'col' ;
            var popOverContent;
                var html = getTemplate();
                popOverContent = $compile(html)(scope);
            var options = {
                content: popOverContent,
                placement: "bottom",
                html: true,
                //title: scope.title
            };
            $(element).popover(options);
            $('body').on('click', function (e) {
                $(element).each(function () {
                    // hide any open popovers when the anywhere else in the body is clicked
                    if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
                        $(this).popover('hide');
                    }
                });
            });
        }
    };
});

Upvotes: 4

Views: 1615

Answers (1)

Vincent Elcrin
Vincent Elcrin

Reputation: 101

As said in the comment by nikos it looks quite complicated. You seems to be mixing scopes, directives and templates. You might want to have a look at the documentation.

Anyway in the mean time here is an alternative to your solution.

html:

<div ng-app="example"> 
<span class="tk-action-s">
    <button priority-over class="fa fa-star col"></button>
</span>

<script type="text/ng-template" id="priorityPopover">
    <div class="btn-group">
        <label class="btn btn-danger" btn-radio="'high'" ng-click="changePriority('high')" uncheckable>High</label>
        <label class="btn btn-warning" btn-radio="'medium'" ng-click="changePriority('medium')" uncheckable>Medium</label>
        <label class="btn btn-primary" btn-radio="'low'" ng-click="changePriority('low')" uncheckable>Low</label>
    </div>
</script>

directive:

angular.module('example', []).directive('priorityOver', function ($compile, $templateCache) {
return {
    restrict: "AC",
    link: function (scope, element, attrs) {
        scope.changePriority = function (priority) {
            $(element).removeClass("low medium high");
            $(element).addClass(priority);
        };
        $(element).popover({
            content: $compile($templateCache.get('priorityPopover').trim())(scope),
            placement: "bottom",
            html: true,
            trigger: 'focus'
        });
    }
};

});

Note how template is externalized from the directive and loaded using the $templateCache service. Also no more transclusion and we expose the behaviour of adding and removing the style from the button via the scope. Allowing us accessing the element on which the directive is applied. Comes also handy when you want to do unit testing for example.

Upvotes: 1

Related Questions