220
votes

I am trying to toggle the class of an element using ng-class

<button class="btn">
  <i ng-class="{(isAutoScroll()) ? 'icon-autoscroll' : 'icon-autoscroll-disabled'}"></i>
</button>

isAutoScroll():

$scope.isAutoScroll = function()
{
    $scope.autoScroll = ($scope.autoScroll) ? false : true;
    return $scope.autoScroll;
}

Basically, if $scope.autoScroll is true, I want ng-class to be icon-autoscroll and if its false, I want it to be icon-autoscroll-disabled

What I have now isn't working and is producing this error in the console

Error: Lexer Error: Unexpected next character at columns 18-18 [?] in expression [{(isAutoScroll()) ? 'icon-autoscroll' : 'icon-autoscroll-disabled'}].

How do I correctly do this?

EDIT

solution 1: (outdated)

<button class="btn" ng-click="autoScroll = !autoScroll">
  <i ng-class="{'icon-autoscroll': autoScroll, 'icon-autoscroll-disabled': !autoScroll}"></i>
</button>

EDIT 2

solution 2:

I wanted to update the solution as Solution 3, provided by Stewie, should be the one used. It is the most standard when it comes to ternary operator (and to me easiest to read). The solution would be

<button class="btn" ng-click="autoScroll = !autoScroll">
  <i ng-class="autoScroll ? 'icon-autoscroll' : 'icon-autoscroll-disabled'"></i>
</button>

translates to:

if (autoScroll == true) ? //use class 'icon-autoscroll' : //else use 'icon-autoscroll-disabled'

6
can't use conditionals in angular expressions per docs => No Control Flow Statements: you cannot do any of the following in angular expression: conditionals, loops, or throw. Use another function or directive - charlietfl
@Ronnie I saw your solution, and it was so cool. but I wonder why the autoScroll here will just effect in each button ? (I tested this with multiple buttons, and it works well too) I mean, when I click each button, it effect just that button, instead of all buttons. - zx1986

6 Answers

440
votes

How to use conditional in ng-class:

Solution 1:

<i ng-class="{'icon-autoscroll': autoScroll, 'icon-autoscroll-disabled': !autoScroll}"></i>

Solution 2:

<i ng-class="{true: 'icon-autoscroll', false: 'icon-autoscroll-disabled'}[autoScroll]"></i>

Solution 3 (angular v.1.1.4+ introduced support for ternary operator):

<i ng-class="autoScroll ? 'icon-autoscroll' : 'icon-autoscroll-disabled'"></i>

Plunker

14
votes

As alternate solution, based on javascript logic operator '&&' which returns the last evaluation, you can also do this like so:

<i ng-class="autoScroll && 'icon-autoscroll' || !autoScroll && 'icon-autoscroll-disabled'"></i>

It's only slightly shorter syntax, but for me easier to read.

10
votes

Add more than one class based on the condition:

<div ng-click="AbrirPopUp(s)" 
ng-class="{'class1 class2 class3':!isNew, 
           'class1 class4': isNew}">{{ isNew }}</div>

Apply: class1 + class2 + class3 when isNew=false,

Apply: class1+ class4 when isNew=true

6
votes
<div data-ng-init="featureClass=false" 
     data-ng-click="featureClass=!featureClass" 
     data-ng-class="{'active': featureClass}">
    Click me to toggle my class!
</div>

Analogous to jQuery's toggleClass method, this is a way to toggle the active class on/off when the element is clicked.

1
votes

autoscroll will be defined and modified in the controller:

<span ng-class= "autoscroll?'class_if_true':'class_if_false'"></span>

Add multiple classes based on condition by:

<span ng-class= "autoscroll?'first second third':'classes_if_false'"></span>
-1
votes

I made this work in this way:

<button class="btn" ng-click='toggleClass($event)'>button one</button>
<button class="btn" ng-click='toggleClass($event)'>button two</button>

in your controller:

$scope.toggleClass = function (event) {
    $(event.target).toggleClass('active');
}