221

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'

2
  • 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 Commented Mar 13, 2013 at 21:59
  • @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. Commented Oct 2, 2013 at 7:15

6 Answers 6

440

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

Sign up to request clarification or add additional context in comments.

4 Comments

The second example is cleaner, but it's ridiculous that you can't put the variable you're evaluating at the front of the expression... it just reads funny. Imagine looking at the expression as an if statement: "if (variable) true: do this, false: do that... ugh #fullynerdy
@Stewie Faaakin gorgeous mate, love how it looks like real code and not some bastardized expression markup :D
Actually evaluating the value first is quite useful as it avoids accidentally assigning the variable a new value.
Ternary is exactly what I was looking for. Good job providing three examples with the version support details.
14

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.

Comments

10

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

Comments

5
<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.

3 Comments

Could you provide some more information on your answer in English? How is it different from the answers that are already here?
I'm not sure why this answer has many negatives votes?? This is the solution that actually worked better for me than the others above...
I think the description is badly written and people react to the word "jQuery".What the description is meant to say is "This is analogue to the toggleClass function in JQuery". BTW, do you need to init the variable?
1

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>

Comments

-1

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');
}

3 Comments

While that does work, you're mixing angular and jQuery. You should try and avoid that if you can. What was originally asked can be done without a click event. What if you have another button that is supposed to toggle this class on your button above? It won't update now because you're changing it on click and not through ng-class
I understand. My point is you don't need to use jQuery anything to achieve the answer to the original question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.