AEngineer
AEngineer

Reputation: 152

How do I dynamically style uib-accordion-group

I have created a uib-accordion in my Angular website and can get most of the functionality I want, with dynamic content changing accordingly.

I am having trouble styling the uib-accordion-group dynamically.

<uib-accordion-group panel-class="panel-danger">
    <uib-accordion-heading>
      Accordion Heading 1

Is fine and colours the whole heading Red/Pink, I want to change this to panel-warning or panel-info based on other variables on the page.

<uib-accordion-group panel-class="{{getPanelColor()}}">
    <uib-accordion-heading>
      Accordion Heading 1

The function seems to be called correctly and is triggered correctly with ng-click elsewhere.

I appears that I cannot change the value panel-class uses dynamically. So in this instance getPanelColor() returns 'panel-danger', 'panel-info' or 'panel-warning' depending on other variables. If I print this return value out on the page in another div or whatever it changes correctly. If I refresh the page the correct colours are displayed for the changed panel-group.

Is there another way of setting the color - I don't know what the classes are for the accordion-group. I have tried changing the color of a div withing the panel, but this is a child element and does not change the color of the whole heading.

Any help much appreciated. (I'll come up with a JSFiddle if the question is not clear)

Upvotes: 2

Views: 9047

Answers (2)

Predhin
Predhin

Reputation: 51

Use an interpolated expression in the class attribute, for example:

 class="{{!ctrl.valid?'notValid':'valid'}}"

Upvotes: 2

masa
masa

Reputation: 2800

If you look at the HTML after the panel-class has changed and Angular has digested the change, you will see this line:

<div class="panel panel-danger" ... panel-class="panel-default">

That is, there is a mismatch between class and panel-class (the former has panel-danger, whereas the latter has panel-default). The uib-accordion-group directive simply does not handle the change in the wanted manner.

One workaround is to add ng-if to the whole group:

<uib-accordion-group ng-if="render" panel-class="{{getPanelColor()}}">

... and just before you want to change panel-class, remove the whole element temporarily, so that Angular re-renders it from scratch. Hopefully, the following code explains the principle:

$scope.render = true;
$scope.panelColor = 'panel-danger';

$scope.setPanelColor = function(val) {
    $scope.panelColor = val;
    $scope.render = false;
    $timeout(function () {
        $scope.render = true;
   });
};

$scope.getPanelColor = function() {
    return $scope.panelColor;
};

See the proposal in action: http://plnkr.co/edit/XfJiPnNi1z4F9cgIVxxw?p=preview. Press 'Clear panel color OK'.

The downside is that the removal of the element causes some flickering.

I have added another button 'Clear panel color FAIL' that shows what happens in your failing case. Here is what the HTML looks like after you press the button, notice the mismatch panel-danger vs. panel-default:

enter image description here

Upvotes: 3

Related Questions