542

Is there any way to make an expression for something like ng-class to be a conditional?

For example, I have tried the following:

<span ng-class="{test: 'obj.value1 == \'someothervalue\''}">test</span> 

The issue with this code is that no matter what obj.value1 is, the class test is always applied to the element. Doing this:

<span ng-class="{test: obj.value2}">test</span> 

As long as obj.value2 does not equal a truthy value, the class in not applied. Now I can work around the issue in the first example by doing this:

<span ng-class="{test: checkValue1()}">test</span> 

Where the checkValue1 function looks like this:

$scope.checkValue1 = function() { return $scope.obj.value === 'somevalue'; } 

I am just wondering if this is how ng-class is supposed to work. I am also building a custom directive where I would like to do something similar to this. However, I can't find a way to watch an expression (and maybe that is impossible and the reason why it works like this).

Here is a plnkr to show what I mean.

5

11 Answers 11

626

Your first attempt was almost right, It should work without the quotes.

{test: obj.value1 == 'someothervalue'} 

Here is a plnkr.

The ngClass directive will work with any expression that evaluates truthy or falsey, a bit similar to Javascript expressions but with some differences, you can read about here. If your conditional is too complex, then you can use a function that returns truthy or falsey, as you did in your third attempt.

Just to complement: You can also use logical operators to form logical expressions like

ng-class="{'test': obj.value1 == 'someothervalue' || obj.value2 == 'somethingelse'}" 
5
  • 2
    Thanks, for whatever reason, I though that because this was an expression as the value of the object, the entire thing had to be in quotes.
    – ryanzec
    CommentedMay 13, 2013 at 19:51
  • 9
    wrap the class name with ' otherwise if you want to add more classes or if your class has hyphens or underscores it will not work. ng-class="{'test test-2: obj.value1 === 'value'}"CommentedNov 14, 2014 at 11:35
  • 8
    @Andrea, you forgot the closing quote: ng-class="{'test test-2': obj.value1 === 'value'}"
    – ErikE
    CommentedJul 2, 2015 at 12:52
  • For Angular2 (which I was trying to find) use attribute(s) like: [class.test]="obj.value1 == 'someotervalue'".
    – kub1x
    CommentedNov 21, 2016 at 14:34
  • 1
    FYI to readers, you can also have brackets. ng-class="{danger:!enabled || (type === 'WHEEL' && !isOnline) }
    – daCoda
    CommentedNov 11, 2019 at 4:22
237

Using ng-class inside ng-repeat

<table> <tbody> <tr ng-repeat="task in todos" ng-class="{'warning': task.status == 'Hold' , 'success': task.status == 'Completed', 'active': task.status == 'Started', 'danger': task.status == 'Pending' } "> <td>{{$index + 1}}</td> <td>{{task.name}}</td> <td>{{task.date|date:'yyyy-MM-dd'}}</td> <td>{{task.status}}</td> </tr> </tbody> </table> 

For each status in task.status a different class is used for the row.

2
  • It is okay when data loading! But not working when status column is a dropdown and its value changes dynamically!CommentedAug 27, 2024 at 8:06
  • Ohh! Issue resolved! Tripple equal used, that is why class not changed dynamically! e.g: 'warning': task.status === 'Hold' used instead of 'warning': task.status == 'Hold'CommentedAug 27, 2024 at 8:28
120

Angular JS provide this functionality in ng-class Directive. In which you can put condition and also assign conditional class. You can achieve this in two different ways.

Type 1

<div ng-class="{0:'one', 1:'two',2:'three'}[status]"></div> 

In this code class will be apply according to value of status value

if status value is 0 then apply class one

if status value is 1 then apply class two

if status value is 2 then apply class three


Type 2

<div ng-class="{1:'test_yes', 0:'test_no'}[status]"></div> 

In which class will be apply by value of status

if status value is 1 or true then it will add class test_yes

if status value is 0 or false then it will add class test_no

5
  • 1
    what is status in here?CommentedSep 8, 2015 at 18:22
  • Status is value which you wants to check or validate according to which class will be apply.CommentedSep 10, 2015 at 10:28
  • 4
    Like this way as it is more flexible and less insane when dealing with multiple valuesCommentedNov 12, 2015 at 17:19
  • How about using it for multiple classes. Like, <div ng-class="{0:'one', 1:'two',2:'three'}[status], {0:'one', 1:'two'}[status1]"></div>CommentedJul 21, 2016 at 6:56
  • 1
    can we use this in such a case like: <div ng-class="{'Image' || 'image': 'image-icon', 'Video' || 'video' || 'aVideo' || 'bVideo' : 'video-icon'}[resource.type]"></div>CommentedSep 22, 2016 at 6:50
89

I see great examples above but they all start with curly brackets (json map). Another option is to return a result based on computation. The result can also be a list of css class names (not just map). Example:

ng-class="(status=='active') ? 'enabled' : 'disabled'" 

or

ng-class="(status=='active') ? ['enabled'] : ['disabled', 'alik']" 

Explanation: If the status is active, the class enabled will be used. Otherwise, the class disabled will be used.

The list [] is used for using multiple classes (not just one).

0
    56

    There is a simple method which you could use with html class attribute and shorthand if/else. No need to make it so complex. Just use following method.

    <div class="{{expression == true ? 'class_if_expression_true' : 'class_if_expression_false' }}">Your Content</div> 
    0
      38

      I am going to show you two methods by which you can dynamically apply ng-class

      Step-1

      By using ternary operator

      <div ng-class="condition?'class1':'class2'"></div> 

      Output

      If your condition is true then class1 will be applied to your element else class2 will be applied.

      Disadvantage

      When you will try to change the conditional value at run time the class somehow will not changed. So I will suggest you to go for step2 if you have requirement like dynamic class change.

      Step-2

      <div ng-class="{value1:'class1', value2:'class2'}[condition]"></div> 

      Output

      if your condition matches with value1 then class1 will be applied to your element, if matches with value2 then class2 will be applied and so on. And dynamic class change will work fine with it.

      Hope this will help you.

      0
        37

        Angular syntax is to use the : operator to perform the equivalent of an if modifier

        <div ng-class="{ 'clearfix' : (row % 2) == 0 }"> 

        Add clearfix class to even rows. Nonetheless, expression could be anything we can have in normal if condition and it should evaluate to either true or false.

        1
        • 1
          Nice! Also, inside ng-repeat you can use $even to set class. E.g. ng-class="$even ? 'even' : 'odd'". Other nifty bools inside the ng-repeat are $first, $last, $even, $odd...
          – Max
          CommentedJul 15, 2015 at 8:43
        16

        Using function with ng-class is a good option when someone has to run complex logic to decide the appropriate CSS class.

        http://jsfiddle.net/ms403Ly8/2/

        HTML:

        <div ng-app> <div ng-controller="testCtrl"> <div ng-class="getCSSClass()">Testing ng-class using function</div> </div> </div> 

        CSS:

        .testclass { Background: lightBlue} 

        JavaScript:

        function testCtrl($scope) { $scope.getCSSClass = function() { return "testclass "; } } 
        1
        • 2
          I think this mixes up the concerns. A controller should be more abstract and not care about css classes, but rather state. Based on the state, the css classes should be applied in the template. This way the controller is independent of the template and easier reusable.
          – Hugo G
          CommentedJul 27, 2016 at 23:11
        10

        ng-class is a Directive of core AngularJs. In which you can use "String Syntax", "Array Syntax", "Evaluated Expression", " Ternary Operator" and many more options described below:

        ngClass Using String Syntax

        This is the simplest way to use ngClass. You can just add an Angular variable to ng-class and that is the class that will be used for that element.

        <!-- whatever is typed into this input will be used as the class for the div below --> <input type="text" ng-model="textType"> <!-- the class will be whatever is typed into the input box above --> <div ng-class="textType">Look! I'm Words! 

        Demo Example of ngClass Using String Syntax

        ngClass Using Array Syntax

        This is similar to the string syntax method except you are able to apply multiple classes.

        <!-- both input boxes below will be classes for the div --> <input type="text" ng-model="styleOne"> <input type="text" ng-model="styleTwo"> <!-- this div will take on both classes from above --> <div ng-class="[styleOne, styleTwo]">Look! I'm Words! 

        ngClass Using Evaluated Expression

        A more advanced method of using ngClass (and one that you will probably use the most) is to evaluate an expression. The way this works is that if a variable or expression evaluates to true, you can apply a certain class. If not, then the class won't be applied.

        <!-- input box to toggle a variable to true or false --> <input type="checkbox" ng-model="awesome"> Are You Awesome? <input type="checkbox" ng-model="giant"> Are You a Giant? <!-- add the class 'text-success' if the variable 'awesome' is true --> <div ng-class="{ 'text-success': awesome, 'text-large': giant }"> 

        Example of ngClass Using Evaluated Expression

        ngClass Using Value

        This is similar to the evaluated expression method except you just able to compares multiple values with the only variable.

        <div ng-class="{value1:'class1', value2:'class2'}[condition]"></div> 

        ngClass Using the Ternary Operator

        The ternary operator allows us to use shorthand to specify two different classes, one if an expression is true and one for false. Here is the basic syntax for the ternary operator:

        ng-class="$variableToEvaluate ? 'class-if-true' : 'class-if-false'"> 

        Evaluating First, Last or Specific Number

        If you are using the ngRepeat directive and you want to apply classes to the first, last, or a specific number in the list, you can use special properties of ngRepeat. These include $first, $last, $even, $odd, and a few others. Here's an example of how to use these.

        <!-- add a class to the first item --> <ul> <li ng-class="{ 'text-success': $first }" ng-repeat="item in items">{{ item.name }}</li> </ul> <!-- add a class to the last item --> <ul> <li ng-class="{ 'text-danger': $last }" ng-repeat="item in items">{{ item.name }}</li> </ul> <!-- add a class to the even items and a different class to the odd items --> <ul> <li ng-class="{ 'text-info': $even, 'text-danger': $odd }" ng-repeat="item in items">{{ item.name }}</li> </ul> 
          9

          For Angular 2, use this

          <div [ngClass]="{'active': dashboardComponent.selected_menu == 'mapview'}">Content</div> 
          1
          • To expand upon this, for Angular 2 you apply a class and also a class modifier in an if/else conditional using an array like so: [ngClass]="['base-class', thread.isActive ? 'base-class--active' : '']"
            – Matt Rabe
            CommentedAug 31, 2018 at 0:49
          9

          use this

          <div ng-class="{states}[condition]"></div> 

          for example if the condition is [2 == 2], states are {true: '...', false: '...'}

          <div ng-class="{true: 'ClassA', false: 'ClassB'}[condition]"></div> 
          2
          • but if i have 3 or more conditions, this wouldn't work? since this will only return true and false conditons
            – Ali
            CommentedJul 5, 2018 at 13:19
          • conditions means true or false. You mean something with more than 2 values?? @AlyAlAmeen
            – Saeed
            CommentedJul 5, 2018 at 16:05

          Start asking to get answers

          Find the answer to your question by asking.

          Ask question

          Explore related questions

          See similar questions with these tags.