angularjsangular-ui-bootstrap

AngularJS and UI-Bootstrap Tabs, using ng-class to modify tab


I'm working with AngularJS and UI-Bootstrap on a project with ui-tabs.

The rough layout is this:

<uib-tabset>
    <uib-tab ng-repeat="tab in tabs" heading="{{tab.TAB_NAME}} : {{tab.Questions|sumByKey:'count'}} of {{tab.Questions.length}}" active="tab.active" disable="tab.disabled">

    <!-- Repeated Content -->

    </uib-tab>
</uib-tabset>

sumByKey:'count' is a filter that calculates the sum of the 'count' field in the repeated tab object. This tracks questions that have been answered, and tab.Questions.length counts the number of questions repeated in the tab.

I can display both in the tab name as I'm doing here, and this works, so in each tab the Tab name is the name : questions-answered of total-questions, i.e.: 'Parking: 1 of 5'.

What I'm trying to do is use ng-class to add a 'completed' class to the tab when these numbers are equal, and all the questions in that tab have been answered.

I can add a class='complete' to the tab, and that works, but trying to make any use of ng-class doesn't work at all, not even ng-class="complete".

Is there a way to do this? Can ng-class be used with uib-tabs? Is there some other mechanism to evaluate an expression and modify the class on the tab?


Solution

  • I'm afraid you can't use ng-class directly on the ui-tab. The issue here is that the contents (and attributes) of the ui-tab is transcluded into this. Which has its own ng-class that's clobbering yours. Here's the only workaround I've managed to find/use.

    Use class along with ng-class like this:

    <uib-tabset>
        <uib-tab class="{{complete}}" ng-repeat="tab in tabs" heading="{{tab.TAB_NAME}} : {{tab.Questions|sumByKey:'count'}} of {{tab.Questions.length}}" active="tab.active" disable="tab.disabled">
    
        <!-- Repeated Content -->
    
        </uib-tab>
    </uib-tabset>
    

    Note, however, that complete will have to be a string for it to work properly. If it's a boolean, you'd probably have better luck doing:

    <uib-tabset>
        <uib-tab class="{{complete ? 'complete':''}}" ng-repeat="tab in tabs" heading="{{tab.TAB_NAME}} : {{tab.Questions|sumByKey:'count'}} of {{tab.Questions.length}}" active="tab.active" disable="tab.disabled">
    
        <!-- Repeated Content -->
    
        </uib-tab>
    </uib-tabset>
    

    Should you need to put multiple classes, I'd create a function that returns the classes in a string:

    <uib-tabset>
        <uib-tab class="{{isCompleted}}" ng-repeat="tab in tabs" heading="{{tab.TAB_NAME}} : {{tab.Questions|sumByKey:'count'}} of {{tab.Questions.length}}" active="tab.active" disable="tab.disabled">
    
        <!-- Repeated Content -->
    
        </uib-tab>
    </uib-tabset>
    

    In controller:

    $scope.isCompleted = function () {
        // some logic
        return 'complete done';
    }
    

    Hope that helps you somewhat.