ng-class condition changes, but not updating classes - javascript

I have a very strange issue. I have to set an active class on the appropriate <li> when the $scope.selectedCat == cat.id. The list is generated with ng-repeat. If selectedCat is false, the 'Browse All Categories' list item (outside of ng-repeat) is set to active. setCat() sets the value of the $scope.selectedCat variable:
<div id="cat-list" ng-controller="CatController">
<li ng-class="{'active': {{selectedCat == false}}}">
<a>
<div class="name" ng-click="setCat(false)" >Browse All Categories</div>
</a>
</li>
<li class="has-subcat" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': {{selectedCat == cat.id}}}">
<a>
<div cat class="name" ng-click="setCat({{cat.id}})" ng-bind-html="cat.name | highlight:catsearch"></div>
</a>
</li>
</div>
When the page loads, everything works fine (snapshot from FireBug):
<li ng-class="{'active': true}" class="ng-scope active">
<!-- ngRepeat: cat in cats | filter:catsearch -->
<li class="has-subcat ng-isolate-scope" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': false}">
However when I set $scope.selectedClass to a cat.id value, the condition within ng-class gets evaluated correctly, but ng-class won't update the classes accordingly:
<li ng-class="{'active': false}" class="ng-scope active"> <!--Right here!-->
<!-- ngRepeat: cat in cats | filter:catsearch -->
<li class="has-subcat ng-isolate-scope" ng-repeat="cat in cats | filter:catsearch" ng-class="{'active': true}">
Please note that in the first line active class stays set, while ng-class evaluates to false. In the last line active is not set, while ng-class evaluates to true.
Any ideas why it doesn't work? What's the correct Angular way of doing this?

Replace:
ng-class="{'active': {{selectedCat == cat.id}}}"
With:
ng-class="{'active': selectedCat == cat.id}"
You never need to nest those curly braces like that, in Angular.
Have a look at the ng-class documentation for some more examples.

Instead of
ng-class="{'active': {{selectedCat == cat.id}}}"
use
ng-class="{active: selectedCat == cat.id}"

Hi i'm also facing the same problem. i solved the problem by the way instead of assigning the value directly to ng-class, call the separate method and return the value.
ex :
ng-class="getStyleClass(cat)"
$scope.getStyleClass = function(cat) {
return "active: selectedCat == cat.id";
}
roughly i coded. please change the method as per your requirement.

Expanding on the answer #Cerbrus gave:
Replace:
ng-class="{'active': {{selectedCat == cat.id}}}"
With:
ng-class="{'active': selectedCat == cat.id}"
I had an issue with an expression using a filter, that would not evaluate properly without double curly braces {{ }}.
Example: ng-class="{'active': {{ selectedCat | filter:catType }} == cat.id}"
I solved it by putting parentheses instead of curly braces.
Solution: ng-class="{'active': ( selectedCat | filter:catType ) == cat.id}"

Did you solve it?
In my opinion you should use
ng-class="{'active': {{controller.selectedCat == cat.id}}}"
With:
ng-class="{'active': controller.selectedCat == cat.id}"
this will help you.

Related

ng-class with condition and function in one ng-class directive

I want ng-class to have a condition and a function call. How do I make the changes necessary to:
<li ng-repeat="t in tabs" ng-class="{'active1':t.active,clickmenu(t.route)}" ng-click='clickMainMenu($index,t)'><div class='custom-menu-li' >{{t.heading | translate }}</div>
</li>
so as to make ng-class have a condition and a function in one ng-class directive.
controller.js
$scope.isActive = function(t) {
if (t.active) {
clickmenu(t.route);
return true;
}
}
template.html
<li ng-repeat="t in tabs"
ng-class="{'active1': isActive(t)}"
ng-click='clickMainMenu($index,t)'>
<div class='custom-menu-li' >{{t.heading | translate }}</div>
</li>
NOTE: This is not the ideal thing to do. Your clickmenu will get called for every digest cycle.
You can do like this using &&:
<li ng-repeat="t in tabs" ng-class="{'active1':t.active && clickmenu(t.route)}" ng-click='clickMainMenu($index,t)'><div class='custom-menu-li' >{{t.heading | translate }}</div>
</li>

changing span text in li using angularjs

I have html something like...
<ul id="sidemenu" class="wraplist wrapper-menu">
<li class="auto" ng-class='{"active": active == 1 }' ng-click="makeActive(1)">
<span class="arrow material-icons">arrow_down</span>
<li>
<li class="auto" ng-class='{"active": active == 2 }' ng-click="makeActive(2)">
<span class="arrow material-icons">arrow_down</span>
<li>
<ul>
on ng-click=makeActive(), I want to change the value 'arrow_down' to 'arrow_right' of that particular < li> element only. and if again the same is clicked I want to change it to 'arrow_down'. Rest all < li> will have span text unchanged. How can I do this using angularjs? i.e. by using angular.element? OR is there any other way?
keyboardArrow refers to only one variable. So you have to create two scope variables: keyboardArrow1 and keyboardArrow2
<ul id="sidemenu" class="wraplist wrapper-menu">
<li class="auto" ng-class='{"active": active == 1 }' ng-click="makeActive(1)">
<span class="arrow material-icons">{{ keyboardArrow1 }}</span>
<li>
<li class="auto" ng-class='{"active": active == 2 }' ng-click="makeActive(2)">
<span class="arrow material-icons">{{ keyboardArrow2 }}</span>
<li>
<ul>
Update
According to your needs, here is a plunker.
Updated my answer from our discussion in comments.
1) In your controller, define keyboardArrow1 and keyboardArrow2:
$scope.keyboardArrow1 = 'A';
$scope.keyboardArrow1 = 'B';
2) You can now display theses values like this:
<ul>
<li ng-class="{'active': active == keyboardArrow1}" ng-click="makeActive(keyboardArrow1)">
{{keyboardArrow1}}
</li>
<li ng-class="{'active': active == keyboardArrow2}" ng-click="makeActive(keyboardArrow2)">
{{keyboardArrow2}}
</li>
</ul>
Note that I also changed the ng-class condition.
3) When clicking a <li>, call makeActive():
$scope.makeActive = function(arrow) {
$scope.active = arrow;
}

Angular 2 getting object object while Class binding

I, am trying to bind the class in the pagination with the following code.
<ul class="pagination hidden-xs pull-right">
<li *ngFor="let pagItem of _pagination">
<a style="cursor: pointer;"
(click)="paginationClick($event)"
id="{{pagItem.pageNo}}"
[ngClass]="{'active': pagItem.pageNo === currentPage}">
{{pagItem.pageNo}}
</a>
</li>
</ul>
In the comparison I am getting object object
Here is the response from the api
The Page and Id is bind successfully. However I am getting the object object on class binding
Here is the image
This is only because you use an Array at
[ngClass]="{'active': pagItem.pageNo === currentPage}"
However your code should works.
this has to be used when you have many possible class result like this :
[ngClass]="{'active': pagItem.pageNo === currentPage, 'inactive': pagItem.pageNo !== currentPage}"
You could also do this to avoid the [Object, Object] rendering,
[class.active]="pagItem.pageNo === currentPage"
Be sure that your variable currentPage is set in your component and shared the same type.
Try this and ensure pagItem.pageNo and currentPage are the same type.
<ul class="pagination hidden-xs pull-right">
<li *ngFor="let pagItem of _pagination">
<a style="cursor: pointer;"
(click)="paginationClick($event)"
id="{{pagItem.pageNo}}"
[class.active]="pagItem.pageNo === currentPage">
{{pagItem.pageNo}}
</a>
</li>
</ul>
I had the same issue and [ngClass] didn't work. Then I changed to different syntax and it solved the problem.
[class.your-css-class]="yourVariable"
Your code should work if you use a ternary expression:
[ngClass]="pageItem.pageNo === currentPage ? 'active': ''"

simple tab system in Angularjs error

So I'm trying to create a simple tab system in angularjs, but whenever I try to bind data on ng-click on the a or li tags of my template I get this error:
Syntax Error: Token '' {1} at column {2} of the expression [{3}] starting at [{4}].
I been searching for hours can't figure out what's causing the problem
here's my code:
<div id="tabs">
<ul>
<li ng-repeat="file in files" ng-click="tab = {{$index}}">
{{file.file_name}}.{{file.file_extension}}
</li>
</ul>
</div>
<!-- tab container -->
<div class="tab-content">
<div class="tab" ng-repeat="doc in files" ng-show="tab == {{$index}}">
{{doc.file_name}}.{{doc.file_extension}}
</div>
</div>
I have tried wrapping {{$index}} in single quotes, that fixes the problem but the tabs don't work when clicked.
You could move this out of the inline logic and into a function, for example $scope.setTabIndex, like so:
$scope.setTabIndex = function(index) {
$scope.tab = index;
}
And then in your markup:
<li ng-repeat="file in files" ng-click="setTabIndex($index)">
And for the ng-show, just remove the curly braces around $index:
<div class="tab" ng-repeat="doc in files" ng-show="tab == $index">
Here's as jsBin

AngularJS - ngRepeat with multiple object types

I have a list of items. An item can be a number of things, let's say the list is something like so :
[userObject , vehicleObject , userObject , animalObject , animalObject]
Now I want to render the list with ngRepeat directive that will use a template according to the type of the object (Polymorphic rendering). can this be done?
maybe something like (ng-use is an hypothetically directive):
<ul>
<li ng-repeat="item in items">
<img ng-use="item.type == 'user'" ng-src="item.src">
<a ng-use="item.type == 'vehicle'">{{item.link}}</a>
<span ng-use="item.type == 'animal'">{{item.name}}</span>
</li>
</ul>
<ul>
<li ng-repeat="item in items" ng-switch="item.type">
<img ng-switch-when="user" ng-src="item.src">
<a ng-switch-when="vehicle">{{item.link}}</a>
<span ng-switch-when="animal">{{item.name}}</span>
</li>
</ul>
API reference:
http://docs.angularjs.org/api/ng.directive:ngSwitch
Although this doesn't use ng-switch, it does get round the problem of not having a type field, which #DotNetHaggis pointed out.
<div ng-repeat="field in fields">
<div ng-if="field.user !== undefined">user info</div>
<div ng-if="field.vehicle !== undefined">vehicle info</div>
<div ng-if="field.animal !== undefined">animal info</div>
</div>

Categories