AngularJS ng-class multiple conditions with OR operator
Asked Answered
F

5

26

I try to find out the good syntax for adding classes depending on angular values. I want to activate a class regarding 2 conditions (one on live user changes, and one on loading datas) with a OR operator.

Here is the line :

 <a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
    <i class="fa orange" ng-class="{'fa-star': (favorite || (fav==myfav.id)), 'fa-star-o': !favorite}"></i>
 </a>

I tried some different codes like this one :

 ng-class="{'fa-star': favorite, 'fa-star': (fav==myfav.id), 'fa-star-o': !favorite}"

without any success. Can someone help me finding the good syntax ?

Finkelstein answered 18/6, 2014 at 14:5 Comment(4)
It should be {'fa-star': favorite || fav == myfav.id, 'fa-star-o': !favorite}. See a similar example in this plunkr. I tried to replace that code with ng-class="{'has-error': ctrl.submitted && 1 == 1} and it works.Cliffcliffes
Parens should be working just as well. If I change your Plunkr code and add them to your AND expression, everything still works. I suppose OP has some other problem with their code.Sabbath
Yes this was my first code but it seems it does not apply the class. I tested the fav == myfav.id outside and it returns "true" as it should be.Finkelstein
Oh. Could it be something about logic : if !favorite but fav==myfav.id the result would be both fa-star fa-star-o and then the last one applies and visually doesn't change the icon. So I'm not sure my "switch" works in this caseFinkelstein
B
38

Try this.

<a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
 <i class="fa orange" ng-class="{'fa-star': favorite || fav==myfav.id, 'fa-star-o': !favorite}"></i>

No need the brackets.

Birecree answered 6/7, 2015 at 5:20 Comment(5)
This doesn't work as expected. The alternate condition seems to be ignored when one model is updated.Chill
@Chill Did you mean, when variable favorite = false and fav == myFav.id? It will result in add both classes 'fa-star' and 'fa-star-o'.Birecree
The issue is with the OR operator, not the second class. When one of the conditions changes, it overrides the other condition.Chill
@Chill by override , what exactly do you mean, could you elaborate a bit. also if you could tell what exactly do you want should happen and its not happening , this would clear any wrong assumptions that we have madeWeaks
Unfortunately I'm having trouble reproducing the issue I was seeing. I may have to retract.Chill
L
10

Once you have to add some logic behind ng-class it's always better to stick to using the controller to do that. You can do it two of either ways: JSON syntax (same as in your HTML, just more readable) or obviously JavaScript.

HTML (JSON) Syntax

HTML

<i ng-class="getFavClassIcon(myFav.id)"></i>

JS

$scope.getFavClassIcon= function (favId) {
    return {
        'fa-star-o' : !$scope.favorite,
        'fa-star'   : $scope.favorite || $scope.fav === favId
    };
};

Good Old IF-statement (JavaScript)

HTML

<i ng-class="getFavClassIcon(myFav.id)"></i>

JS

$scope.getFavClassIcon= function (favId) {
    if (!$scope.favorite) {
        return 'fa-star-o';
    } else if ($scope.favorite) { // obviously you can use OR operator here
        return 'fa-star';
    } else if ($scope.fav === favId) {
        return 'fa-star';
    }
};
Lymn answered 20/7, 2015 at 14:24 Comment(2)
Old fashioned if is the best here, especially if multiple variables affect the class nameHuh
This is a brilliant way to do it - simple enough that anybody can pick it up and understand. Thanks.Erlandson
W
4

The HTML will remain the same

<a href="" ng-click="addFavorite(myfav.id);favorite=!favorite">
    <i ng-class="{'fa-star-o':!favorite,'fa-star':favorite||fav===myfav.id}"></i>
</a>

But the order in which classes are present in your CSS file will matter

The fa-star class will apply either when favorite is true or fav===myfav.id returns true.

Therefore if after clicking once , suppose fav===myfav.id returns true and keeps on returning true , even when clicking again , then the class fa-star will be applied always from then on.

If by default favorite is false , then fa-star-o will be applied when template is loaded the first time, but after the first click ,when favorite is set to true , it will get removed. Then on second click , when favorite is set to false again , fa-star-o it will get applied but in this case , fa-star class will also be applied as fa===myfav.id condition would be still returning true (Assuming that is the case).

Therefore you will need to prioritize which class needs to get applied for sure when it is present on the element as case can arise when both classes can be present at the same time on the element. For example if fa-star-o class takes higher priority, then put it below the fa-star in your CSS , like for example

.fa-star {
  border: 1px solid #F00;
}
.fa-star-o {
  border: 1px solid #000;
}

See working demo at http://plnkr.co/edit/Dh59KUU41uWpIkHIaYrO?p=preview

Weaks answered 14/7, 2015 at 19:31 Comment(0)
G
2

You can use expression with ng-class

  <i class="fa orange" ng-class="favorite || fav == myfav.id ? 'fav' : 'no-fav'"></i>
Geier answered 19/7, 2015 at 16:5 Comment(0)
L
0

For example: In my scenario i need to apply uppercase class in some condition and in some condition i do not need to apply that uppercase class.

inputTextCapitalSmall(assetId) {
    return {
      'uppercase': assetId !== 'TELEKURS' && assetId !== 'REUTERS' && assetId !== 'S&P',
    };
  }

<form [formGroup]="querySearchForm" >
  <input autocomplete="off" matInput id="assetIdTypeValue" [ngClass]="inputTextCapitalSmall(querySearchForm.value.assetIdType)" >
</form>
Lankton answered 13/12, 2019 at 8:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.