Ng-style with condition - angularjs

How can I apply style on some item in a list that satisfy listed condition:
<div data-ng-repeat="item in items">
<div data-ng-style="{'background' : 'red' : item.selected}> {{item.name}}
<div>
<div>
How is it possible to apply this style on item that is selected.

Try this code,
<div data-ng-repeat="item in items">
<div data-ng-style="item.selected && {'background-color':'red'}">
{{item.name}}
<div>
<div>

I think it would be best to use ng-class for your problem. You then make a new class for the red background, eg:
<style>
.red-background{
background-color: red;
}
</style>
And then use this class according to the condition:
<div data-ng-class="{'red-background':item.selected}">{{item.name}}</div>
(don't forget the single quotes around the class name, they are easily overlooked)

Ironically I just looked this up, the correct thing is to obviously use classes as they have this designed within them.
However, you can do conditionals thanks to the JavaScript ability to return the last value with &&
<div ng-style="conditional && { 'background' : 'red' } || !conditional && { 'background' : 'green' }"> show me the background </div>

Please refer below
function simpleController($scope) {
$scope.items = [
{
selected: false,
name: 'first'
}
,
{
selected: true,
name: 'second'
}
];
}
.red
{
background:red}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app>
<body ng-controller="simpleController">
<div data-ng-repeat="item in items">
<div ng-class="{'red' : item.selected}"> {{item.name}}
<div>
<div>
</body>
</html>

ng-style="{'background': (desktop) ? '#ffffff' : ''}"
Explanation:
{CssProperty: Condition ? if condition is True : If condition is False}
CssProperty : meaning background, color, font-size etc..
Condition: just like a If statment..
after the : define the property value for the true and false Condition .for the the CssProperty.
here we have no value if condition is false.
any true or false value should be the Proper value for the CSSProperty.
So for background it's #ffffff or White.

You can use this method described further here. (example below)
angular.module('app', []);
function myCtrl($scope){
$scope.items = [
{ name: 'a', selected: 'false' },
{ name: 'b', selected: 'true' }
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<html ng-app>
<body ng-controller="myCtrl">
<div ng-repeat="item in items">
<div ng-style="{color: {true:'red'}[item.selected]}">{{item.name}}</div>
</div>
</body>
</html>

On Angular >9 the syntax is following:
[ngStyle]="{'background-color': item.selected ? '#f00' : ''}"
Make sure you do not add a semicolon (;) at the end of the style expression as this breaks the functionality

Related

AngularJS checkbox avoid counting when uncheck checkBox

Here is my running code in Plunker
I got a bug: When I uncheck the answer, I do not want to count how many times we select this answer? We will only count the number when we check the answer. For example, I check "Yes", I uncheck "Yes", I check "Yes" again, I will only show "Yes" was selected 2 times, instead of 3 times.
I read some posts about this issue, but cannot make it work by using checked property?
<input type="checkbox" ng-change="answerSelected(ans)" ng-model="checkAnswer">{{ans.answer}}
change the ng-model to object property like ng-model="ans.checkAnswer"
<input type="checkbox" ng-change="answerSelected(ans)" ng-model="ans.checkAnswer">{{ans.answer}}
Then change the function like this
$scope.answerSelected = function(checkAnswer) {
if (checkAnswer.checkAnswer) {
checkAnswer.count++;
}
$scope.answerBoxSelected = true;
};
Demo
Just add a check like this,
if (checkAnswer) {
ans.count++;
$scope.answerBoxSelected = true;
}
DEMO
// Code goes here
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.questions = [{
id: 1,
question: "Do you like Foo?",
answers: [{
answer: "Yes",
count: 0,
id: 1,
question_id: 1
}, {
answer: "No",
count: 0,
id: 2,
question_id: 1
}]
},
{
id: 2,
question: "Do you like Bar?",
answers: [{
answer: "Yes",
count: 0,
id: 1,
question_id: 2
}, {
answer: "No",
count: 0,
id: 2,
question_id: 2
}]
}
]
$scope.question_index = 0;
$scope.answerSelected = function(checkAnswer,ans) {
if (checkAnswer) {
ans.count++;
}
$scope.answerBoxSelected = true;
};
$scope.nextQuestion = function() {
$scope.question_index++;
$scope.answerBoxSelected = false;
};
});
<!DOCTYPE html>
<html>
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="form-group" ng-if="question_index < questions.length">
<div ng-repeat="item in questions">
<div ng-if="question_index == $index">
<h2>{{item.question}}</h2>
<div ng-repeat="ans in item.answers">
<input type="checkbox" ng-change="answerSelected(checkAnswer,ans)" ng-model="checkAnswer">{{ans.answer}}
<br>
</div>
<div ng-if="answerBoxSelected" class="alert alert-warning">
<h3>Answer Selection Summary</h3>
<div ng-repeat="ans in item.answers">
<p>
"{{ans.answer}}" Has been selected {{ans.count}}
<span ng-if="ans.count == 0">time</span>
<span ng-if="ans.count > 0">times</span>
<p>
</div>
</div>
<button class="btn btn-info btn-lg" ng-if="answerBoxSelected && question_index < questions.length - 1" ng-click="nextQuestion()">Next Question > </button>
</div>
</div>
</div>
<div class="alert alert-success" ng-if="question_index == questions.length - 1 && answerBoxSelected">
Congratulations! You answered all the questions. Good job!
</div>
</div>
<script src="script.js">
</script>
</body>
</html>
One workaround is to pass the element itself to the answerSelected method, and check its checkAnswer property. We will only increment the count if this property is true.
<input type="checkbox" ng-change="answerSelected(ans, this)" ng-model="checkAnswer">{{ans.answer}}
$scope.answerSelected = function(checkAnswer, elem) {
if (elem.checkAnswer === true) {
checkAnswer.count++;
}
$scope.answerBoxSelected = true;
};
You can call the function conditionally only when the checbox is checked:
<input type="checkbox" ng-change="!checkAnswer || answerSelected(ans)" ng-model="checkAnswer">{{ans.answer}}
When the checkbox is checked, checkAnswer will evaluate to true, and the function will be called.
When the checkbox is unchecked, checkAnswer will evaluate to false, and the function will not be called.
Here's a plunker

How to combain two inline functions in ng-class [duplicate]

Can we have multiple expression to add multiple ng-class ?
for eg.
<div ng-class="{class1: expressionData1, class2: expressionData2}"></div>
If yes can anyone put up the example to do so.
.
To apply different classes when different expressions evaluate to true:
<div ng-class="{class1 : expression1, class2 : expression2}">
Hello World!
</div>
To apply multiple classes when an expression holds true:
<!-- notice expression1 used twice -->
<div ng-class="{class1 : expression1, class2 : expression1}">
Hello World!
</div>
or quite simply:
<div ng-class="{'class1 class2' : expression1}">
Hello World!
</div>
Notice the single quotes surrounding css classes.
For the ternary operator notation:
<div ng-class="expression1? 'class1 class2' : 'class3 class4'">
An incredibly powerful alternative to other answers here:
ng-class="[ { key: resulting-class-expression }[ key-matching-expression ], .. ]"
Some examples:
1. Simply adds 'class1 class2 class3' to the div:
<div ng-class="[{true: 'class1'}[true], {true: 'class2 class3'}[true]]"></div>
2. Adds 'odd' or 'even' classes to div, depending on the $index:
<div ng-class="[{0:'even', 1:'odd'}[ $index % 2]]"></div>
3. Dynamically creates a class for each div based on $index
<div ng-class="[{true:'index'+$index}[true]]"></div>
If $index=5 this will result in:
<div class="index5"></div>
Here's a code sample you can run:
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope){
$scope.items = 'abcdefg'.split('');
});
.odd { background-color: #eee; }
.even { background-color: #fff; }
.index5 {background-color: #0095ff; color: white; font-weight: bold; }
* { font-family: "Courier New", Courier, monospace; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MyCtrl">
<div ng-repeat="item in items"
ng-class="[{true:'index'+$index}[true], {0:'even', 1:'odd'}[ $index % 2 ]]">
index {{$index}} = "{{item}}" ng-class="{{[{true:'index'+$index}[true], {0:'even', 1:'odd'}[ $index % 2 ]].join(' ')}}"
</div>
</div>
Yes you can have multiple expression to add multiple class in ng-class.
For example:
<div ng-class="{class1:Result.length==2,class2:Result.length==3}"> Dummy Data </div>
Using a $scope method on the controller, you can calculate what classes to output in the view. This is especially handy if you have a complex logic for calculating class names and it will reduce the amount of logic in your view by moving it to the controller:
app.controller('myController', function($scope) {
$scope.className = function() {
var className = 'initClass';
if (condition1())
className += ' class1';
if (condition2())
className += ' class2';
return className;
};
});
and in the view, simply:
<div ng-class="className()"></div>
Your example works for conditioned classes (the class name will show if the expressionDataX is true):
<div ng-class="{class1: expressionData1, class2: expressionData2}"></div>
You can also add multiple classes, supplied by the user of the element:
<div ng-class="[class1, class2]"></div>
Usage:
<div class="foo bar" class1="foo" class2="bar"></div>
Here is an example comparing multiple angular-ui-router states using the OR || operator:
<li ng-class="
{
warning:
$state.includes('out.pay.code.wrong')
|| $state.includes('out.pay.failed')
,
active:
$state.includes('out.pay')
}
">
It will give the li the classes warning and/or active, depening on whether the conditions are met.
Below active and activemenu are classes and itemCount and ShowCart is expression/boolean values.
ng-class="{'active' : itemCount, 'activemenu' : showCart}"
With multiple conditions
<div ng-class="{'class1' : con1 || can2, 'class2' : con3 && con4}">
Hello World!
</div>
Found another way thanks to Scotch.io
<div ng-repeat="step in steps" class="step-container step" ng-class="[step.status, step.type]" ng-click="onClick(step.type)">
This was my reference.PATH
Other way we can create a function to control "using multiple class"
CSS
<style>
.Red {
color: Red;
}
.Yellow {
color: Yellow;
}
.Blue {
color: Blue;
}
.Green {
color: Green;
}
.Gray {
color: Gray;
}
.b {
font-weight: bold;
}
</style>
Script
<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>
Using it
<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>
You can refer to full code page at ng-class if example
I use this:
[ngClass]="[{
'basic':'mat-basic-button',
'raised':'mat-raised-button',
'stroked':'mat-stroked-button'
}[
button.style ?? 'raised'
]]"

Can I get the value from the key from ng-repeat x in xx | unique x.key

I have a collection of items that represent a grouping by one property. I want to create a list of items grouped by the value of this property and in each list present the value of this group once and then all the items that belong to the group.
Something like the following
<div ng-repeat="items in itemcollection | unique: 'groupkey'">
<h3>{{items.groupkey}}</h3>
<div ng-repeat="item in items">
<label>{{item.name}}</label>
</div>
</div>
So if I have a itemscollection like the following:
{{ groupkey: 1; name: 'Ada'}, { groupkey: 1; name: 'Beda'}, {groupkey: 2; name: 'Ceda'}}
So after the generation of divs and labels the result should be
<div>
<h3>1</h3>
<div><label>Ada</label></div>
<div><label>Beda</label></div>
</div>
<div>
<h3>2</h3>
<div><label>Ceda</label></div>
</div>
Is it possible to create this or do I need to handle the creating of the elements to better construct the data to make this happen?
This filter does what you want : https://github.com/a8m/angular-filter#groupby
Yes. Its possible by the combination of orderBy and filter function in angularJS. The following code will work :
var app = angular.module("myApp", []);
app.controller("lists", function($scope) {
$scope.list = [{
groupkey: 1,
name: 'Ada'
}, {
groupkey: 1,
name: 'Beda'
}, {
groupkey: 2,
name: 'Ceda'
}];
});
<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
</head>
<body>
<div ng-controller="lists">
<div ng-repeat="items in list | orderBy:'groupkey'">
<h3>{{items.groupkey}}</h3>
<label>{{items.name}}</label>
</div>
</div>
</body>
</html>
Hope it works for you :)
Not tested but something like this I guess should work
<div ng-repeat="items in itemcollection | unique: 'groupkey'">
<h3>{{items.groupkey}}</h3>
<div ng-repeat="item in items | filter:{'groupkey': items.groupkey}:true">
<label>{{item.name}}</label>
</div>
</div>
If you make sure the itemcollection is sorted by groupkey you may display the groupkey header only when the groupkey differs from the previous groupkey. Then you achieve to only show the groupkey header once per group. Here is an example:
angular.module('myapp',[]).controller("thectrl", function($scope) {
$scope.itemcollection = [{ groupkey: 1, name: 'Ada'},
{ groupkey: 1, name: 'Beda'},
{groupkey: 2, name: 'Ceda'},
{groupkey: 2, name: 'D'}];
$scope.itemcollection.sort(function(a,b) { return a.groupkey-b.groupkey;});
});
The HTML:
<div ng-app="myapp" ng-controller="thectrl">
<div ng-repeat="item in itemcollection track by $index" >
<h3 ng-if="$index===0 || itemcollection[$index-1].groupkey!==item.groupkey">{{item.groupkey}}</h3>
<label>{{item.name}}</label>
</div>
</div>
And a working fiddle here:
https://jsfiddle.net/vuksyeyh/

How can i make text change color when i cliked in my cell

I want to change the colors of my cell, so in my table i do this on my td
data-ng-class="{selected: selected.id == price.id && price.isMinPrice}"
if is selected and is a min price i want have a colors
but this code line do nothing, why ?
Maybe you need something like this:
Here you can define any conditional in a ternary operator
data-ng-class="selected.id == price.id && price.isMinPrice ? 'selected-class' : ''"
You can also add more classes for both cases like this:
data-ng-class="some-condition ? 'selected-class' : 'no-selected-class another-class'"
Full example:
angular.module('test', []);
angular.module('test').controller('controll', ['$scope',
function($scope) {
$scope.items = [{
value: 1,
selected: false
}, {
value: 2,
selected: true
}, {
value: 3,
selected: false
}]
}
]);
.selected-class {
color: red;
}
<div ng-app="test">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="controll">
<table style="width:100%">
<tr ng-repeat="item in items">
<td data-ng-class="item.selected ? 'selected-class' : ''">{{item.value}}</td>
</tr>
</table>
</div>
</div>

How to use ng-if to test if a variable is defined

Is there a way to use ng-if to test if a variable is defined, not just if it's truthy?
In the example below (live demo), the HTML displays a shipping cost for the red item only, because item.shipping is both defined and nonzero. I'd like to also display a cost for the blue item (shipping defined but zero), but not for the green item (shipping not defined).
JavaScript:
app.controller('MainCtrl', function($scope) {
$scope.items = [
{
color: 'red',
shipping: 2,
},
{
color: 'blue',
shipping: 0,
},
{
color: 'green',
}
];
});
HTML:
<body ng-controller="MainCtrl">
<ul ng-repeat='item in items'>
<li ng-if='item.color'>The color is {{item.color}}</li>
<li ng-if='item.shipping'>The shipping cost is {{item.shipping}}</li>
</ul>
</body>
I tried doing ng-if='angular.isDefined(item.shipping)', but it didn't work. Nor did ng-if='typeof(item.shipping) !== undefined'.
Try this:
item.shipping!==undefined
I edited your plunker to include ABOS's solution.
<body ng-controller="MainCtrl">
<ul ng-repeat='item in items'>
<li ng-if='item.color'>The color is {{item.color}}</li>
<li ng-if='item.shipping !== undefined'>The shipping cost is {{item.shipping}}</li>
</ul>
</body>
plunkerFork
You can still use angular.isDefined()
You just need to set
$rootScope.angular = angular;
in the "run" phase.
See update plunkr: http://plnkr.co/edit/h4ET5dJt3e12MUAXy1mS?p=preview

Resources