I am trying to toggle viewing categories of items within a very long list, based on what the user wants to see. I want to toggle viewing everything, just meetings, just events or nothing. (this is a small example I really have about 15 categories)
<ul>
<li class="cal-meeting">meeting title</li>
<li class="cal-event">event title</li>
<!-- … the list goes on with various events and meetings -->
So I have the following checkboxes to toggle the viewable items:
<input type="checkbox" checked (click)="toggleCal('meeting')">
<input type="checkbox" checked (click)="toggleCal('event')">
// checkboxes are initially checked however I will make this dynamic saved in DB for user preference
In my angular component in TypeScript I have the function:
toggleCal(toggle_items) {
if (toggle_items === 'meeting') {
// this.display_meeting is initially set to true in ngOnInit
this.display_meeting = !this.display_meeting;
if ( this.display_meeting ) {
// set class cal-meeting to display: block;
} else {
// set class cal-meeting to display: none;
}
}
// do the same thing if toggle_items === 'event'
}
How do I change the display value of the classes cal-meeting and cal-event in my Typescript? I assume just changing the CSS values of the classes is the best way.
I did try:
document.getElementsByClassName('cal-meeting').style.display = 'none';
But I get an error saying "Property 'style' does not exist on type 'HTMLCollectionOf'"
try to convert your selection as HTMLElement
const element = <HTMLElement> document.getElementsByClassName('cal-meeting')[0];
then use :
element.style.display = 'none';
also you can use *ngif for remove it but if you want to use javascript's function to change style you should convert it to HTMLElement
but you can use angular [ngStyle]="{'property': expression}" for changing style like :
<li class="cal-meeting" [ngStyle]="{'display': !this.display_meeting ? 'none': 'block'}">meeting title</li>
or you can add class for example if you have class like :
.d-none: {display: none}
.d-block: {display: block}
you can use it in typescript like:
export class MyComponent implements OnInit {
hidingClass: string = '';
toggleCal(toggle_items) {
if (toggle_items === 'meeting') {
this.display_meeting = !this.display_meeting;
if ( this.display_meeting ) {
this.hidingClass = 'd-block'
} else {
this.hidingClass = 'd-none'
}
}
// do the same thing if toggle_items === 'event'
}
just use it in your html element:
<li class="cal-meeting" [ngClass]="hidingClass">meeting title</li>
If it's just toggle the view, why you did not put something simple like this
<li class="cal-meeting" *ngIf="this.display_meeting">meeting title</li>
I have a list and the plugin (dragula) I used, adds certain CSS class on certain action. I am using Angular 5. I want to find out the presence of certain class (myClass) and remove that and replace with (yourClass). In jQuery we can do that like this
$( "p" ).removeClass( "myClass" ).addClass( "yourClass" );
How can I achieve this in Angular5. Here the main issue is that myClass is added automatically to the selected li by the plugin. So using a function I cant set the class.
When I tried with renderer2, it is removing the CSS class and adding another class. But it is adding only to the first li. My code is:
let myTag ;
myTag = this.el.nativeElement.querySelector("li");
this.renderer.addClass(myTag, 'gu-mirrorss')
this.renderer.removeClass(myTag, 'dragbox');
<div class="right-height" id ='dest' [dragula]='"second-bag"' [dragulaModel]="questions">
{{ questions.length == 0 ? ' Drag and drop questions here ' : ' '}}
<li #vc data-toggle="tooltip" data-placement="bottom" title= {{question.questionSentence}} class="well dragbox" *ngFor="let question of questions; let i = index" [attr.data-id]="question.questionId" [attr.data-index]="i" (click)="addThisQuestionToArray(question,i, $event)" [class.active]="isQuestionSelected(question)" #myId > {{question.questionId}} {{question.questionSentence}}</li>
</div>
Import ElementRef from angular core and define in constructor then try below code:
Below line of code will give you first occurrence of <p> tag from Component. querySelector gives you first item and querySelectorAll gives you all items from DOM.
import { Component, ElementRef } from "#angular/core";
constructor(private el: ElementRef) {
}
let myTag = this.el.nativeElement.querySelector("p"); // you can select html element by getelementsByClassName also, please use as per your requirement.
Add Class:
if(!myTag.classList.contains('myClass'))
{
myTag.classList.add('myClass');
}
Remove Class:
myTag.classList.remove('myClass');
You can use id in your html
<button #namebutton class="btn btn-primary">login</button>
add viewchild in your.ts
#ViewChild('namebutton', { read: ElementRef, static:false }) namebutton: ElementRef;
create a function that will trigger the event
actionButton() {
this.namebutton.nativeElement.classList.add('class-to-add')
setTimeout(() => {
this.namebutton.nativeElement.classList.remove('class-to-remove')
}, 1000);
}
and call the function.
If your native element is undefined check this answer
Angular: nativeElement is undefined on ViewChild
Here are multiple ways to pass classes
<some-element [ngClass]="'first second'">...</some-element>
<some-element [ngClass]="['first', 'second']">...</some-element>
<some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
<some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
<some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
From Official Docs
If you want to change all li.myClass, you can do like this:
Note the #questions in the container div.
Component.ts
#ViewChild('questions') questions: any;
questions.nativeElement.querySelectorAll('.myClass').forEach(
question => {
question.classList.remove('myClass');
question.classList.add('newClass');
}
)
Component.html
<div #questions class="right-height" id ='dest' [dragula]='"second-bag"' [dragulaModel]="questions">
{{ questions.length == 0 ? ' Drag and drop questions here ' : ' '}}
<li
#vc
data-toggle="tooltip"
data-placement="bottom"
title= {{question.questionSentence}}
class="well dragbox"
*ngFor="let question of questions; let i = index"
[attr.data-id]="question.questionId"
[attr.data-index]="i"
(click)="addThisQuestionToArray(question,i, $event)"
[class.active]="isQuestionSelected(question)"
#myId>
{{question.questionId}} {{question.questionSentence}}
</li>
</div>
The Best and easiest way is : -
If student is null then dissabled else not. Use this in button attribute. If you are using bootstrap theme
[ngClass]="{disabled: (students === null) ? true : false}"
If 'yourFlag' is true, 'classB' is enabled.
This worked in angular10.
class="classA {{yourFlag ? 'classB' : ''}}"
<ul>
<li (click)="AddColor($event)">ONE</li>
<li (click)="AddColor($event)">TWO</li>
<li (click)="AddColor($event)">THREE</li>
</ul>
AddColor(e){
e.srcElement.style.color="blue"
}
I have the above list when i click any one of the li item out of 3, the clicked label color should be changed. when i click another all item colors should be revert back to original and change color of current clicked item.
#Mehdi said, you should not access DOM directly untill there is a need.
Always keep in mind, drive your view with data rather than accessing
DOM directly
I have forked and working snippet https://plnkr.co/edit/fgINMc?p=preview
When using Angular, you don't want to directly manipulate the DOM element. Rather let angular deal with it.
In your example, you can generate your list from an array you declare in the code like so
export class YourClass{
links:any;
activeLink = -1;
//...
constructor(){
this.links = ['ONE','TWO','THREE']
}
//...
}
and then in your template you could have :
<ul>
<li *ngFor="let link of links; let i = index"
(click)="activeLink = i"
[ngClass]="activeLink == i? 'blue' : '' " >
</li>
</ul>
and declare a css class blue :
.blue{
color:blue;
}
Lets say you have an array that is rendered in a ul with an li for each element and a property on the controller called selectedIndex. What would be the best way to add a class to the li with the index selectedIndex in AngularJS?
I am currently duplicating (by hand) the li code and adding the class to one of the li tags and using ng-show and ng-hide to show only one li per index.
If you don't want to put CSS class names into Controller like I do, here is an old trick that I use since pre-v1 days. We can write an expression that evaluates directly to a class name selected, no custom directives are necessary:
ng:class="{true:'selected', false:''}[$index==selectedIndex]"
Please note the old syntax with colon.
There is also a new better way of applying classes conditionally, like:
ng-class="{selected: $index==selectedIndex}"
Angular now supports expressions that return an object. Each property (name) of this object is now considered as a class name and is applied depending on its value.
However these ways are not functionally equal. Here is an example:
ng-class="{admin:'enabled', moderator:'disabled', '':'hidden'}[user.role]"
We could therefore reuse existing CSS classes by basically mapping a model property to a class name and at the same time keep CSS classes out of Controller code.
ng-class supports an expression that must evaluate to either
A string of space-delimited class names, or
An array of class names, or
A map/object of class names to boolean values.
So, using form 3) we can simply write
ng-class="{'selected': $index==selectedIndex}"
See also How do I conditionally apply CSS styles in AngularJS? for a broader answer.
Update: Angular 1.1.5 has added support for a ternary operator, so if that construct is more familiar to you:
ng-class="($index==selectedIndex) ? 'selected' : ''"
My favorite method is using the ternary expression.
ng-class="condition ? 'trueClass' : 'falseClass'"
Note: Incase you're using a older version of Angular you should use this instead,
ng-class="condition && 'trueClass' || 'falseClass'"
I'll add to this, because some of these answers seem out of date. Here's how I do it:
<class="ng-class:isSelected">
Where 'isSelected' is a javascript variable defined within the scoped angular controller.
To more specifically address your question, here's how you might generate a list with that:
HTML
<div ng-controller="ListCtrl">
<li class="ng-class:item.isSelected" ng-repeat="item in list">
{{item.name}}
</li>
</div>
JS
function ListCtrl($scope) {
$scope.list = [
{"name": "Item 1", "isSelected": "active"},
{"name": "Item 2", "isSelected": ""}
]
}
See: http://jsfiddle.net/tTfWM/
See: http://docs.angularjs.org/api/ng.directive:ngClass
Here is a much simpler solution:
function MyControl($scope){
$scope.values = ["a","b","c","d","e","f"];
$scope.selectedIndex = -1;
$scope.toggleSelect = function(ind){
if( ind === $scope.selectedIndex ){
$scope.selectedIndex = -1;
} else{
$scope.selectedIndex = ind;
}
}
$scope.getClass = function(ind){
if( ind === $scope.selectedIndex ){
return "selected";
} else{
return "";
}
}
$scope.getButtonLabel = function(ind){
if( ind === $scope.selectedIndex ){
return "Deselect";
} else{
return "Select";
}
}
}
.selected {
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app ng-controller="MyControl">
<ul>
<li ng-class="getClass($index)" ng-repeat="value in values" >{{value}} <button ng-click="toggleSelect($index)">{{getButtonLabel($index)}}</button></li>
</ul>
<p>Selected: {{selectedIndex}}</p>
</div>
I faced a similar problem recently and decided to just create a conditional filter:
angular.module('myFilters', []).
/**
* "if" filter
* Simple filter useful for conditionally applying CSS classes and decouple
* view from controller
*/
filter('if', function() {
return function(input, value) {
if (typeof(input) === 'string') {
input = [input, ''];
}
return value? input[0] : input[1];
};
});
It takes a single argument, which is either a 2-element array or a string, which gets turned into an array that is appended an empty string as the second element:
<li ng-repeat="item in products | filter:search | orderBy:orderProp |
page:pageNum:pageLength" ng-class="'opened'|if:isOpen(item)">
...
</li>
If you want to go beyond binary evaluation and keep your CSS out of your controller you can implement a simple filter that evaluates the input against a map object:
angular.module('myApp.filters, [])
.filter('switch', function () {
return function (input, map) {
return map[input] || '';
};
});
This allows you to write your markup like this:
<div ng-class="muppets.star|switch:{'Kermit':'green', 'Miss Piggy': 'pink', 'Animal': 'loud'}">
...
</div>
The was I recently did that was doing this:
<input type="password" placeholder="Enter your password"
ng-class="{true: 'form-control isActive', false: 'isNotActive'}[isShowing]">
The isShowing value is a value that is located on my controller that gets toggled with the click of a button and the parts between the single parenthesis are classes I created in my css file.
EDIT: I would also like to add that codeschool.com has a free course that is sponsored by google on AngularJS that goes over all of this stuff and then some. There is no need to pay for anything, just signup for an account and get going!
Best of luck to you all!
Ternary operator has just been added to angular parser in 1.1.5.
So the simplest way to do this is now :
ng:class="($index==selectedIndex)? 'selected' : ''"
We can make a function to manage return class with condition
<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) {
switch(strValue) {
case "It is Red":return "Red";break;
case "It is Yellow":return "Yellow";break;
case "It is Blue":return "Blue";break;
case "It is Green":return "Green";break;
case "It is Gray":return "Gray";break;
}
}
}]);
</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
I am new to Angular but have found this to solve my issue:
<i class="icon-download" ng-click="showDetails = ! showDetails" ng-class="{'icon-upload': showDetails}"></i>
This will conditionally apply a class based on a var.
It starts off with a icon-download as a default, the using ng-class, I check the status of showDetails if true/false and apply class icon-upload. Its working great.
Hope it helps.
This works like a charm ;)
<ul class="nav nav-pills" ng-init="selectedType = 'return'">
<li role="presentation" ng-class="{'active':selectedType === 'return'}"
ng-click="selectedType = 'return'"><a href="#return">return
</a></li>
<li role="presentation" ng-class="{'active':selectedType === 'oneway'}"
ng-click="selectedType = 'oneway'"><a href="#oneway">oneway
</a></li>
</ul>
This will probably get downvoted to oblivion, but here is how I used 1.1.5's ternary operators to switch classes depending on whether a row in a table is the first, middle or last -- except if there is only one row in the table:
<span class="attribute-row" ng-class="(restaurant.Attributes.length === 1) || ($first ? 'attribute-first-row': false || $middle ? 'attribute-middle-row': false || $last ? 'attribute-last-row': false)">
</span>
This is in my work multiple conditionally judge:
<li ng-repeat='eOption in exam.examOptions' ng-class="exam.examTitle.ANSWER_COM==exam.examTitle.RIGHT_ANSWER?(eOption.eoSequence==exam.examTitle.ANSWER_COM?'right':''):eOption.eoSequence==exam.examTitle.ANSWER_COM?'wrong':eOption.eoSequence==exam.examTitle.RIGHT_ANSWER?'right':''">
<strong>{{eOption.eoSequence}}</strong> |
<span ng-bind-html="eOption.eoName | to_trusted">2020 元</span>
</li>
Here is another option that works well when ng-class can't be used (for example when styling SVG):
ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"
(I think you need to be on latest unstable Angular to use ng-attr-, I'm currently on 1.1.4)
well i would suggest you to check condition in your controller with a function returning true or false .
<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>
and in your controller check the condition
$scope.getTodayForHighLight = function(today, date){
return (today == date);
}
partial
<div class="col-md-4 text-right">
<a ng-class="campaign_range === 'thismonth' ? 'btn btn-blue' : 'btn btn-link'" href="#" ng-click='change_range("thismonth")'>This Month</a>
<a ng-class="campaign_range === 'all' ? 'btn btn-blue' : 'btn btn-link'" href="#" ng-click='change_range("all")'>All Time</a>
</div>
controller
$scope.campaign_range = "all";
$scope.change_range = function(range) {
if (range === "all")
{
$scope.campaign_range = "all"
}
else
{
$scope.campaign_range = "thismonth"
}
};
If you are using angular pre v1.1.5 (i.e. no ternary operator) and you still want an equivalent way to set a value in both conditions you can do something like this:
ng-class="{'class1':item.isReadOnly == false, 'class2':item.isReadOnly == true}"
If you having a common class that is applied to many elements you can create a custom directive that will add that class like ng-show/ng-hide.
This directive will add the class 'active' to the button if it's clicked
module.directive('ngActive', ['$animate', function($animate) {
return function(scope, element, attr) {
scope.$watch(attr.ngActive, function ngActiveWatchAction(value){
$animate[value ? 'addClass' : 'removeClass'](element, 'active');
});
};
}]);
More info
Just adding something that worked for me today, after much searching...
<div class="form-group" ng-class="{true: 'has-error'}[ctrl.submitted && myForm.myField.$error.required]">
Hope this assists in your successful development.
=)
Undocumented Expression Syntax : Great Website Link... =)
Check this.
The infamous AngularJS if|else statement!!!
When I started using Angularjs, I was a bit surprised that I couldn’t find an if/else statement.
So I was working on a project and I noticed that when using the if/else statement, the condition shows while loading.
You can use ng-cloak to fix this.
<div class="ng-cloak">
<p ng-show="statement">Show this line</span>
<p ng-hide="statement">Show this line instead</span>
</div>
.ng-cloak { display: none }
Thanks amadou
You can use this npm package. It handles everything and has options for static and conditional classes based on a variable or a function.
// Support for string arguments
getClassNames('class1', 'class2');
// support for Object
getClassNames({class1: true, class2 : false});
// support for all type of data
getClassNames('class1', 'class2', ['class3', 'class4'], {
class5 : function() { return false; },
class6 : function() { return true; }
});
<div className={getClassNames({class1: true, class2 : false})} />
I understand this question id for angular, but if anyone is using React or a React-Based Framework (Amplify, NextJS, Serverless, etc.) The solution is significantly easier. The most performant way is with a ternary operator like so:
<div className={condition ? "classnameiftrue" : "classnameiffalse"}>
You can use this strategy to animate the tree if using useState() as each time the state changes it will reload that conditional with the new value.