Angular 2 conditional class active in second condition not working - html

I added code to show the sort direction as well as color for selected column see the plunker
if sortable show up/down arrow: working
if Ascending show down arrow with active color: ACTIVE NOT APPLYING
if descending show up arrow with active color: working
Here is the code to application class conditionally:
<i class="fa fa-lg" [ngClass]="{'fa-sort' : column !== 'ProjectID',
' fa-sort-asc active' : (column === 'ProjectID' && !isDesc),
' fa-sort-desc active' : (column === 'ProjectID' && isDesc) }"
aria-hidden="true"></i>
See ASC and DESC both have active class which is working only with DESC true condition, please see the plunker for more detail.
Here the code after applying all conditions:
<i aria-hidden="true" class="fa fa-lg fa-sort"></i>
<i aria-hidden="true" class="fa fa-lg fa-sort-asc"></i> // active missing
<i aria-hidden="true" class="fa fa-lg fa-sort-desc active"></i>
Any Idea why it is behaving like this:

Conditions in ngClass are applied in order. When the condition in ngClass is evaluated to false, it removes corresponding classes. If the same class is in two conditions, it might be added at first but in the next condition, it will be removed.
Possible solutions would be:
change style classes to .active-asc, .active-desc {color: red;} and then apply them respectively in the conditions;
or
add new condition 'active' : column === 'columnName'

Related

Dynamically format styles in CSS

I am trying to display an icon in a column instead of its text via CSS. However, I have been unable to find right syntax for this piece of code.
My reactjs code has:
return '<div><span class="fa fa-2x fa-star" style="display : [' + item.Status + ' == approved] ? block: none"></span></div>';
}
That results in below code which doesn't work:
<div>
<span class="fa fa-2x fa-star" style="display : [submitted == approved] ? block: none"></span>
</div>
In the above situation when "submitted" != "approved", it ideally shouldn't show the icon but the star icon show up in each row (whether value matches or not).
In chrome, I've also tried below codes and many similar formats but none of them work:
<span class="fa fa-2x fa-star" style="[rejected == approved] ? display: block : display : none"></span>
<span class="fa fa-2x fa-star" style="display : [rejected == approved] ? block : none"></span>
<span class="fa fa-2x fa-star" style="display : "rejected" == "approved" ? block : none"></span>
My requirement is that icon should be visible only when value LHS and RHS value matches, eg: "approved" = "approved".
The solution that worked for me is:
var cssClass = item.Status = "approved" ? "fa fa-2x fa-star" : "myblankcssclass" ; //add various classes using ternary operator.
return '<div><span class=" '+ cssClass + '" </span></div>';
}
You try this:
displayStyle = submitted == approved ? 'block': 'none';
return (
<div>
<span class="fa fa-2x fa-star" style={{ display: displayStyle }}></span>
</div>
)
Code that worked for me:
var cssClass = item.Status = "approved" ? "fa fa-2x fa-star" : "myblankcssclass" ; //add various classes using ternary operator.
return '<div><span class=" '+ cssClass + '" </span></div>';
}

ngClass with multiple conditions false condition not working

I'm trying to use [ngClass] with multiple conditions to change the caret of a open/close panel.
Currently the down arrow works flawlessly.
When I click the arrow and the condition changes to false, it changes the icon to a empty box and is not recognizing the correct class name.
<i [ngClass]="{'fa fa-caret-up pull-right': isActive4 == true,
'fa fa-caret-down pull-right': isActive4 == false}"
(click)="section4Click()"></i>
The section4Click() changes isActive4 to true/false depending on what it was before.
When I inspect element of the box that shows up after I click the down caret (which works), I get the following class name...
fa-caret-up
instead of...
fa fa-caret-up pull-right
Anyone know why this occurs? It seems like its doing half the job...
I've also tried just doing isActive4 and !isActive4, and the same happens.
It's hard to tell from looking at your code. But you can try this:
<i class="fa pull-right" [class.fa-caret-up]="isActive4" [class.fa-caret-down]="!isActive4" (click)="section4Click()"></i>
I would also recommend printing the values to see what you get:
<p>{{ isActive4 === true }}</p>
This will work.
<i class="fa pull-right" [ngClass]="{'fa-caret-up': isActive4 == true,
'fa-caret-down': isActive4 == false}"
(click)="section4Click()"></i>

How to add an ID(selector) for the HTML tags using ng-class

I'm using an icon, which I display based on a condition using ng-class. I want to add ID's for both the HTML tags.
<i ng-show="ctrl.data.length > 1"
ng-class="{'glyphicon glyphicon-chevron-down': !ctrl.isOpen,
'glyphicon glyphicon-chevron-up': ctrl.isOpen}">
</i>
In order to have a dynamic ID value, wrap it in {{}} so that Angular interprets that value.
<i ng-show="ctrl.data.length > 1" id="{{ctrl.isOpen ? 'chevron-up' : 'chevron-down'}}"
ng-class="{'glyphicon glyphicon-chevron-down': !ctrl.isOpen,
'glyphicon glyphicon-chevron-up': ctrl.isOpen}">
</i>

Angular (4 or 2) apply CSS if conditions are met

I've found some code examples that explain how I can apply a class item if conditions are met.
In my .ts file I have the following:
private readNews : boolean = false;
[..]
ngOnInit() {
localStorage.setItem('readNews', 'Read');
if (localStorage.getItem('readNews') != null || '') {
this.readNews = true;
}
}
In my HTML I have the following inline CSS:
<i class="fal fa-cogs fa-5x"></i>
However, what I want it to be is the following:
If this.readNews === true
<i class="fal fa-cogs fa-5x blink"></i>
So it needs to add 'blink' in the CSS when the news is read (which is saved in localStorage).
try like this :
<i [ngClass]="readNews ? 'fal fa-cogs fa-5x blink': 'fal fa-cogs fa-5x'"></i>
Use ngClass
<i [ngClass]="(readNews == 'Read')? 'fal fa-cogs fa-5x blink':'fal fa-cogs fa-5x'" ></i>
or you can call custom functions
[ngClass]="getClass()"
getClass(flag:string) {
let cssClasses;
if(localStorage.getItem('readNews') == 'Read') {
cssClasses = {
'fal': true,
'fa-cogs': true,
'fa-5x': true,
'blink': true
}
} else {
cssClasses = {
'fal': true,
'fa-cogs': true,
'fa-5x': true,
'blink': false
}
}
return cssClasses;
}
<i [class.blink]="readNews"></i>
Based on cheat sheet on https://angular.io/guide/cheatsheet
In HTML:
<i *ngIf="readNews" class="fal fa-cogs fa-5x"></i>
<i *ngIf="!readNews" class="fal fa-cogs fa-5x blink"></i>
And in typescript i would refactor as this to improve readability:
ngOnInit() {
localStorage.setItem('readNews', 'Read');
this.readNews = (localStorage.getItem('readNews') != null || '');
}

Conditionally displaying template content inside ng-repeat

I'm using ng-repeat to loop render an angular template potentially thousands of times, and wondering what is the most efficient way to go about conditionally altering it's display. For example, each item in the loop has a 'type', which has a corresponding icon. There are a few ways to go about this:
Purely css/html - this seems the most efficient angular-wise, but will mean a lot more html in the DOM
<li class="{{item.type}}">
<i class="type-1-icon"></i>
<i class="type-2-icon"></i>
<i class="type-3-icon"></i>
</li>
And then in the css:
li i { display:none; }
li.type-1 i.type-1-icon { display:block; }
li.type-2 i.type-2-icon { display:block; }
li.type-3 i.type-3-icon { display:block; }
Using ng-if - tidies up the dom, but could be less efficient evaluating the ng-if for lots of records?
<li>
<i class="type-1-icon" ng-if="item.type == 'type-1'"></i>
<i class="type-2-icon" ng-if="item.type == 'type-2'"></i>
<i class="type-3-icon" ng-if="item.type == 'type-3'"></i>
</li>
Using ng-switch
<li ng-switch on="item.type">
<i class="type-1-icon" ng-switch-when="type-1"></i>
<i class="type-2-icon" ng-switch-when="type-2"></i>
<i class="type-3-icon" ng-switch-when="type-3"></i>
</li>
Using ng-show (same for ng-hide). Similar to #1 I'm guessing
<li>
<i class="type-1-icon" ng-show="item.type == 'type-1'"></i>
<i class="type-2-icon" ng-show="item.type == 'type-2'"></i>
<i class="type-3-icon" ng-show="item.type == 'type-3'"></i>
</li>
Anyway, I realise that all 4 approaches will work fine, but I'd love to learn a bit more about which is best for a potentially large dataset and why. Thanks!