Shiv Kumar Ganesh
Shiv Kumar Ganesh

Reputation: 3825

AngularJS template inside directive. Change the Style?

The css inside the directive does not compile and leads to single color green itself. I want to have different colors for different values for the value identifier and the css color should change accordingly but it always subsides to the last color for all the thermometer widget. Please help.

angular.module('directives').directive('thermometer', function(){
    return {
        restrict: 'AE'
        , replace: true
        , transclude:true
        ,scope : {
            value : "=",
            maxValue : "=" ,
            text:"@",
            percent:"="
            }
        ,template:  function(element, attrs) {
            var html = '<div style="float:left;margin-left:40px"><style> .donation-meter {margin-right:auto;margin-left:auto; width: 80px; } .donation-meter .glass { background: #e5e5e5; border-radius: 100px 100px 0 0; display: block; height: 100px; margin: 0 35px 10px; padding: 5px; position: relative; width: 20px; } .donation-meter .amount { background:{{color}}; border-radius: 100px; display: block; width: 20px; position: absolute; bottom: 5px; } .donation-meter strong { display: block; text-align: center; } .donation-meter .goal { font-size: 20px; } .donation-meter .total { font-size: 16px; position: absolute; right: 35px; } .bulb { background: #e5e5e5; border-radius: 100px; display: block; height: 50px; margin: 0 35px 10px; padding: 5px; position: relative; top: -20px; right: 15px; width: 50px; } .bulb .red-circle { background: {{color}}; border-radius: 100px; display: block; height: 50px; width: 50px; } .bulb .filler { background: {{color}}; border-radius: 100px 100px 0 0; display: block; height: 30px; width: 20px; position: relative; top: -65px; right: -15px; z-index: 30; } </style>';
            html += '<div class="donation-meter"> <b>{{text}}</b>';
            html +=   '<b class="goal">{{maxValue }}</b> <span class="glass"> <b class="total" style="bottom:{{(value/maxValue)*100}}%">{{value}}';
            html+= '</b> <span class="amount" style="height:{{(value/maxValue)*100}}%"></span> </span> <div class="bulb"> <span class="red-circle"></span> <span class="filler"> <span></span> </span> </div> </div></div>';

            return html;

        }
        ,link:function(scope){

            scope.$watch('value',function(newValue){
                console.log("--------------------------");
                console.log();
                if(newValue==75){
                    scope.color="blue";
                }
                if(newValue==76){
                    scope.color="green";
                }
            });
        }

    }
});

The color always subsides to whatever is the last value. Rest of the time it works fine. Please help.

Upvotes: 3

Views: 1073

Answers (3)

Daniel Beck
Daniel Beck

Reputation: 21475

By putting the variable inside a <style> rule, you're redefining the css class each time your directive gets placed on the page -- so if the first instance of the directive sets

.donation-meter .amount { background:red}

but the next one sets it to

.donation-meter .amount { background:green}

then the last css rule is going to override the previous ones and therefore apply to all .donation-meter .amount elements on the page.

You should extract most of your CSS into a stylesheet rather than re-rendering it for every instance of the directive. For the parts where you need variable style rules, use ng-class where possible:

<div ng-class="{red: newValue < 75, green: newValue >74}">...</div>

or else set the variable style directly on the element rather than on a class rule:

<div style="background-color: {{color}}">

instead of

<style>.foo {background-color: {{color}}</style> <div class="foo"></div>

Upvotes: 0

syldor
syldor

Reputation: 1176

It would be easier to put the template on an outside file, like thermometer.html, you just have to specify the location like this:

angular.module('directives').directive('thermometer', function(){
    return {
        restrict: 'AE'
        , replace: true
        , transclude:true
        ,scope : {
            value : "=",
            maxValue : "=" ,
            text:"@",
            percent:"="
            }
        ; templateUrl: 'thermometer.html'
        ,link:function(scope){

            scope.$watch('value',function(newValue){
                console.log("--------------------------");
                console.log();
                if(newValue==75){
                    scope.color="blue";
                }
                if(newValue==76){
                    scope.color="green";
                }
            });
        }

    }
});

And then create the html file: < div style=...> ... < /div>

Upvotes: 0

Tomer
Tomer

Reputation: 17930

Instead of putting the color on the class .amount put it in the style of the element that has the class .amount:

html+= '</b> <span class="amount" ng-style="{height:(value/maxValue)*100 + '%', background: color}"></span> ...

Upvotes: 1

Related Questions