I would like to add a class based on the value of the scope.
It's not working :(
If the value.statut == 3, I would like to add class todo
Else If the value.statut == 2, I would like to add class done
Else If the value.statut == 1, I would like to add class doing
<span class="label" ng-class="value.statut == 3 ? 'todo' : ''; value.statut == 2 ? 'done' : ''; value.statut == 1 ? 'doing' : '';">Label</span>
The declaration needs to be slightly different:
<span class="label" ng-class="{'todo': value.statut == 3, 'done': value.statut == 2, 'doing': value.statut == 1}">Label</span>
So, the syntax is:
ng-class="{<className>: <predicate>, <className2>: <predicate2>, etc }"
Try this :
<span class="label" ng-class="{'todo': (value.statut == 3), 'done': (value.statut == 2), 'doing': (value.statut == 1)}">Label</span>
ng-class needs an object with key/value. The key is the class name and the value is a boolean.
Reference
https://docs.angularjs.org/api/ng/directive/ngClass
Related
Can someone please explain why this works:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || fruit.type == 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
pear lemon
But this doesn't:
<div ng-repeat="fruit in fruits">
<span ng-hide="fruit.type == 'apple' || 'banana'">
{{fruit.type}}
</span>
</div>
Renders:
// nothing
In Javascript (and most languages I know), comparisons aren't communicable. For every comparison (in this case equality), you unfortunately need a full statement.
In fruit.type == 'apple' || 'banana',
1. fruit.type == 'apple' is evaluated.
2. After that, it || compares the result of that to 'banana', which in Javascript is a truthy value ('' is the only "falsy" string, all other strings are "truthy").
In essence, you end up with fruit.type == 'apple' || TRUE, which will always trigger ng-hide.
in this case its a bad expression fruit.type == 'apple' || 'banana'
|| are used in javascript for "OR" and define a default value to a variable when some reference values is undefined or null for example:
var name = null || "mottaman85";
consolog.log(name);
"mottaman85"
function test(nombreV){
var name = nombreV || "mottaman85";
console.log(name)
}
test();
"mottaman85"
I have 3 variety of template. by $index conditionally i am applying the template.
here is my directive html :
<all-apps-gallery index="$index" app="app" update="update(app)" class="show" ng-repeat="app in allAppsBatch"></all-apps-gallery>
and here is the directive:
var allAppsGallery = function ($compile, $animate) {
return {
restrict : 'E',
replace : true,
templateUrl : '/views/tools/gallery.html', // see below the html
scope : {
index : "=",
update : "&",
app : "="
}
}
}
}
angular
.module("tcpApp")
.directive('allAppsGallery', allAppsGallery);
My `templateUrl''s html :
<div>
<div ng-class="bgr box{{index}}" ng-click="update(app)" ng-if="{{index}} == 0 || {{index}} == 13 || {{index}} == 14 || {{index}} == 15 || {{index}} == 5 ">
<h2>{{app.completion}} % {{index}}</h2>
<span>{{app.name}}</span>
</div>
<div ng-class="bbr box{{index}}" ng-click="update(app)" ng-if="{{index}} == 2 || {{index}} == 3 || {{index}} == 4 || {{index}} == 6 || {{index}} == 10 || {{index}} == 11 || {{index}} == 12">
<h2>{{app.completion}} %</h2>
<span>{{app.name}}</span>
</div>
<div ng-class="bbl box{{index}}" ng-click="update(app)" ng-if="{{index}} == 1 || {{index}} == 7 || {{index}} == 8 || {{index}} == 9 ">
<h2>{{app.completion}} %</h2>
<span>{{app.name}}</span>
</div>
</div>
Here according to the index value, i am switching the template. but it's not working for me. what is the wrong i made here?
Any one figure-out me please?
Thanks in advance.
I am getting this error:
Error Link
ngIf directive expects an expression, and hence you don't need to have interpolation tags {{ }} in it. Attribute value will be parsed and evaluated by Angular, however {{ tags make value an invalid JS expression and cannot be processed.
Correct code would be
ng-if="index == 0 || index == 13 || index == 14 || index == 15 || index == 5 "
I want to change the colors of my cell, so in my table i do this on my td
data-ng-class="{selected.id == price.id && !price.isMinPrice ? 'selected' : '', selected.id == price.id && price.isMinPrice ? 'minSelected' : ''}"
i have this error:
Error: [$parse:syntax] Syntax Error: Token '.' is unexpected,
expecting [:] at column 10 of the expression [{selected.id == price.id
&& !price.isMinPrice ? 'selected' : '', selected.id == price.id &&
price.isMinPrice ? 'minSelected' : ''}] starting at [.id == price.id
&& !price.isMinPrice ? 'selected' : '', selected.id == price.id &&
price.isMinPrice ? 'minSelected' : ''}].
What is wrong ..?
You are using ng-class all wrong and that is why you are getting syntax errors.
You need to give it an object literal:
data-ng-class="{selected: selected.id == price.id && !price.isMinPrice,
minSelected: selected.id == price.id && price.isMinPrice}"
This is also much cleaner than what you were trying to do.
I think that ng-class expects structure like this: {'class-name' : booleanValue}, and if value is true, class will be applied.
So in your case:
data-ng-class="{'selected' : selected.id == price.id && !price.isMinPrice, 'minSelected' : selected.id == price.id && price.isMinPrice}"
and if you want to use ternaty operator, you can use class attribute with {{}}:
class="{{selected.id == price.id && !price.isMinPrice ? 'selected' : ''}}"
I need to take records with null values on top , when I'm sorting by ASC
<tr ng-repeat="footballer in footballers=(footballers | orderBy:predicate)">
predicate : ['team.name','id]
Some footballers have no team, so team object == null and team.name==null, and I need to have them on the top
I wanted to rewrite sort function, but I need to save predicate
You can use something like this in your controller:
$scope.nullsToTop = function(obj) {
return (angular.isDefined(obj.team) ? 0 : -1);
};
And on the HTML:
<tr ng-repeat="footballer in footballers | orderBy:[nullsToTop].concat(predicate)">
This way you can maintain your predicate separately. Just concat the nullsToTop function in the orderBy expression to run it first.
Plunker
Create a function in the controller that will receive as parameter the entity and will return either ['team.name','id] either [] or other values that will help push the non-sortable elements to top/bottom of the list.
EDIT (example)
HTML:
<li ng-repeat="item in items | orderBy:getItemOrder track by $index">...
AngularJS Ctrl:
$scope.getItemOrder = function (entity) {
if (entity.id === null || .... === null) {
return 0;
}
return ['team.name','id];
}
I was able to do it by returning a '+' or a '-' if the value is null, close to what bmleite did but is more contained in the function itself.
1. create a function that adds a + or a - to the null values depending on the sort order (asc or desc) so that they'd always remain at either the top or bottom
function compareAndExcludeNull(element){
var compareWith = $scope.order.propertyName; // in your case that's 'predicate'
var operatorToBottom = $scope.order.reverse ? '+' : '-'; // If decending then consider the null values as smallest, if ascending then consider them biggest
var operatorToTop = $scope.order.reverse ? '-' : '+';
if(element[compareWith] == null){
return operatorToTop;
} else {
return operatorToBottom+element[compareWith];
}
}
if you want to have the null values at the bottom of the sorted array then just switch the operatorToTop with operatorToBottom and vice versa to get:
function compareAndExcludeNull(element){
var compareWith = $scope.order.propertyName; // in your case that's '
var operatorToBottom = $scope.order.reverse ? '+' : '-'; // If decending then consider the null values as smallest, if ascending then consider them biggest
var operatorToTop = $scope.order.reverse ? '-' : '+';
if(element[compareWith] == null){
return operatorToBottom;
} else {
return operatorToTop+element[compareWith];
}
}
2. Call the function and pass the array you're sorting
Javascript:
In my case I am calling this function from HTML and passing different propertyName depending on the column the user is sorting by, in your case you'd just need to pass 'predicate' as the propertyName
$scope.order.sortBy = function(propertyName){
$scope.order.reverse = (propertyName !== null && $scope.order.propertyName === propertyName) ? !$scope.order.reverse : false;
$scope.order.propertyName = propertyName;
$scope.resources = $filter('orderBy')($scope.resources,compareAndExcludeNull,$scope.order.reverse);
};
HTML:
<div>
<span ng-if="showKeywords" class="label label-info" ng-click="order.sortBy('keyword')" style="margin-right: 5px">
Order by Keywords
<span ng-if="order.propertyName=='keyword'" class="glyphicon glyphicon-triangle-{{order.reverse? 'bottom' : 'top'}}">
</span>
</span>
<span ng-if="showWebsites" class="label label-info" ng-click="order.sortBy('res_title')">
Order by Website
<span ng-if="order.propertyName=='res_title'" class="glyphicon glyphicon-triangle-{{order.reverse? 'bottom' : 'top'}}">
</span>
</span>
</div>
I know this is an old post but there is a better way for doing this and could not see it anywhere.
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', ["$scope", function($scope){
$scope.footballers = [
{id: 0, qt: 13},
{id: 1, qt: 2},
{id: 2, qt: 124},
{id: 3, qt: 12125},
{id: null , qt: 122},
{id: 4, qt: -124},
{id: 5, qt: -5235},
{id: 6, qt: 43},
]
}])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="footballer in footballers | orderBy:['id==null || id']">
{{footballer.id}}, {{footballer.qt}}
</div>
</div>
One can also use this to show 'id' with any specific value on top of others
With AngularJS I'm using ng-class the following way:
<div class="bigIcon" data-ng-click="PickUp()"
ng-class="{first:'classA', second:'classB', third:'classC', fourth:'classC'}[call.State]"/>
I'm wondering if I can use the if-else expression to do something similar to this:
<div class="bigIcon" data-ng-click="PickUp()"
ng-class="{first:'classA', second:'classB', else:'classC'}[call.State]"/>
So whenever call.State differs from first or second use classC and avoid specifying each value?
Use nested inline if-then statements (Ternary Operators)
<div ng-class=" ... ? 'class-1' : ( ... ? 'class-2' : 'class-3')">
for example :
<div ng-class="apt.name.length >= 15 ? 'col-md-12' : (apt.name.length >= 10 ? 'col-md-6' : 'col-md-4')">
...
</div>
And make sure it's readable by your colleagues :)
you could try by using a function like that :
<div ng-class='whatClassIsIt(call.State)'>
Then put your logic in the function itself :
$scope.whatClassIsIt= function(someValue){
if(someValue=="first")
return "ClassA"
else if(someValue=="second")
return "ClassB";
else
return "ClassC";
}
I made a fiddle with an example : http://jsfiddle.net/DotDotDot/nMk6M/
I had a situation where I needed two 'if' statements that could both go true and an 'else' or default if neither were true, not sure if this is an improvement on Jossef's answer but it seemed cleaner to me:
ng-class="{'class-one' : value.one , 'class-two' : value.two}" class="else-class"
Where value.one and value.two are true, they take precedent over the .else-class
Clearly! We can make a function to return a CSS class name with following fully example.
CSS
<style>
.Red {
color: Red;
}
.Yellow {
color: Yellow;
}
.Blue {
color: Blue;
}
.Green {
color: Green;
}
.Gray {
color: Gray;
}
.b{
font-weight: bold;
}
</style>
JS
<script>
angular.module('myapp', [])
.controller('ExampleController', ['$scope', function ($scope) {
$scope.MyColors = ['It is Red', 'It is Yellow', 'It is Blue', 'It is Green', 'It is Gray'];
$scope.getClass = function (strValue) {
if (strValue == ("It is Red"))
return "Red";
else if (strValue == ("It is Yellow"))
return "Yellow";
else if (strValue == ("It is Blue"))
return "Blue";
else if (strValue == ("It is Green"))
return "Green";
else if (strValue == ("It is Gray"))
return "Gray";
}
}]);
</script>
And then
<body ng-app="myapp" ng-controller="ExampleController">
<h2>AngularJS ng-class if example</h2>
<ul >
<li ng-repeat="icolor in MyColors" >
<p ng-class="[getClass(icolor), 'b']">{{icolor}}</p>
</li>
</ul>
<hr/>
<p>Other way using : ng-class="{'class1' : expression1, 'class2' : expression2,'class3':expression2,...}"</p>
<ul>
<li ng-repeat="icolor in MyColors">
<p ng-class="{'Red':icolor=='It is Red','Yellow':icolor=='It is Yellow','Blue':icolor=='It is Blue','Green':icolor=='It is Green','Gray':icolor=='It is Gray'}" class="b">{{icolor}}</p>
</li>
</ul>
You can refer to full code page at ng-class if example
The above solutions didn't work for me for classes with background images somehow. What I did was I create a default class (the one you need in else) and set class='defaultClass' and then the ng-class="{class1:abc,class2:xyz}"
<span class="booking_warning" ng-class="{ process_success: booking.bookingStatus == 'BOOKING_COMPLETED' || booking.bookingStatus == 'BOOKING_PROCESSED', booking_info: booking.bookingStatus == 'INSTANT_BOOKING_REQUEST_RECEIVED' || booking.bookingStatus == 'BOOKING_PENDING'}"> <strong>{{booking.bookingStatus}}</strong> </span>
P.S: The classes that are in condition should override the default class i.e marked as !important
This is the best and reliable way to do this.
Here is a simple example and after that you can develop your custom logic:
//In .ts
public showUploadButton:boolean = false;
if(some logic)
{
//your logic
showUploadButton = true;
}
//In template
<button [class]="showUploadButton ? 'btn btn-default': 'btn btn-info'">Upload</button>
A workaround of mine is to manipulate a model variable just for the ng-class toggling:
For example, I want to toggle class according to the state of my list:
1) Whenever my list is empty, I update my model:
$scope.extract = function(removeItemId) {
$scope.list= jQuery.grep($scope.list, function(item){return item.id != removeItemId});
if (!$scope.list.length) {
$scope.liststate = "empty";
}
}
2) Whenever my list is not empty, I set another state
$scope.extract = function(item) {
$scope.list.push(item);
$scope.liststate = "notempty";
}
3) When my list is not ever touched, I want to give another class (this is where the page is initiated):
$scope.liststate = "init";
3) I use this additional model on my ng-class:
ng-class="{'bg-empty': liststate == 'empty', 'bg-notempty': liststate == 'notempty', 'bg-init': liststate = 'init'}"
Use it this way:
<div [ngClass]="{cssClass A: condition 1, cssClass B: condition 2, cssClass C: condition 3}">...</div>
You can try this method:
</p><br /><br />
<p>ng-class="{test: obj.value1 == 'someothervalue' || obj.value2 == 'somethingelse'}<br /><br /><br />
ng-class="{test: obj.value1 == 'someothervalue' || obj.value2 == 'somethingelse'}
You can get complete details from here.