angular 9: Multiple conditions on ngClass inside a ngFor - css

I'm having some issues trying to print the typical star-rating widget in my page using angular. Probably there will be an easier way to show them using css but for now i wanted to do it by code.
<i *ngFor="let star of this.stars" [ngClass]="{
'score__star fas fa-star': star === 'full',
'score__star fas fa-star-half-alt': star === 'half',
'score__star far fa-star': star === 'empty'
}"></i>
this is the code of the widget and this is the content of the array of stars:
(5) ["full", "full", "half", "empty", "empty"]
i'm not sure why, chrome draws properly the first 2 but not the others. From what i have seen in the debugger there are parts of the class that are missed...
<i _ngcontent-lqd-c56="" ng-reflect-ng-class="[object Object]" class=""></i>
<i _ngcontent-lqd-c56="" ng-reflect-ng-class="[object Object]" class=""></i>
<i _ngcontent-lqd-c56="" ng-reflect-ng-class="[object Object]" class="fas fa-star-half-alt"></i>
<i _ngcontent-lqd-c56="" ng-reflect-ng-class="[object Object]" class="score__star far fa-star"></i>
<i _ngcontent-lqd-c56="" ng-reflect-ng-class="[object Object]" class="score__star far fa-star"></i>
Any idea of what i'm missing? I also tried to mix class and ngClass to split the common part of the style but i had the same problem.
Thanks a lot!

I see one workaround for this problem.
Could you change your classes, e.g:
getClasses(star) {
return {
'full' : star === 'full',
'half' : star === 'half',
'empty' : star === 'empty'
}}
Also I'm not sure If you know this but you can pass method to ngClass directive
<i *ngFor="let star of stars" [ngClass]="getClasses(star)">
{{star}}
</i>

Related

How to keep the side bar link active when i change the tabs using angular2

i have a side bar, where in it remains active if im on the screens first tab, if i switch to second tab, the url changes and the sidebar label wont be active.
How can this be solved. Please help.
HTML:
Side bar Code:
<a routerLink="/my-health/my-health-history" [ngClass] = "{'active' : true}" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}" class="list-group-item list-group-item-action justify-content-between"
id="nav-link-1" aria-haspopup="true" aria-expanded="false" aria-controls="nav-submenu-1">
<span><i class="icon-heart g-pos-rel g-top-1 g-mr-8"></i>{{ 'DashboardModule.MYHEALTH' | translate }}
</span>
</a>
TAbs code redirected to pages on click of side bar link:
<div class="myhealth mt7">
<ul class="nav nav-tabs menu">
<li>
<a class="active-link" routerLink="/my-health/my-health-history" routerLinkActive="active-link"
[routerLinkActiveOptions]="{exact: true}">myHealthHistory
</a>
</li>
<li>
<a routerLink="/my-health/my-lifestyle" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">myLifeStyle
</a>
</li>
<li>
<a routerLink="/my-health/my-family-health-history" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">myFamilyHistory
</a>
</li>
</ul>
</div>
If i am in myHealth History tab, then side bar will be active, if i shift to other 2 tabs then side bar wont be active
Using [ngClass] = "{'active' : true}" in tag.
The condition are:
Differ your current URL based on tab change.
ex1: http://test.com/tab1 and http://test.com/tab2
ex2:http://test.com/#tab1 and http://test.com/#tab2
Read url and find string like "tab1 or tab2"
add "Active" class based on this condition
You can check for the current active link in the sidebar component.
Sidebar html
<a routerLinkActive="active-link" [ngClass]="{'active-link': isActive()}" class="list-group-item list-group-item-action justify-content-between"
id="nav-link-1" aria-haspopup="true" aria-expanded="false" aria-controls="nav-submenu-1">
<span><i class="icon-heart g-pos-rel g-top-1 g-mr-8"></i>{{ 'DashboardModule.MYHEALTH' | translate }}
</span>
</a>
Sidebar ts
constructor(private router:Router) {
}
isActive(){
return ["/my-health/my-health-history","/my-health/my-lifestyle","/my-health/my-family-health-history"].includes(this.router.url);
}
Note : the code is written directly to Stackoverflow editor so there could be typo or syntatical error. Please correct yourself.

Set an action for one element in ng-repet clause

i've this code and a little problem working with Ionic and AngularJS.
$scope.changeArrow = function(){
if($scope.down == false){
$scope.down = true;
}else{
$scope.down = false;
}
};
<ion-item ng-repeat="beac in disp" class="item-icon-right" ng-click="changeArrow()">
<b>{{choosen.network}} - {{beac.minor}}</b> • {{beac.viewed}} / {{beac.conf}}
<i class="icon ion-arrow-right-b" ng-show="down"></i>
<i class="icon ion-arrow-down-b" ng-show="!down"></i>
Results:
After click -->>
After click, will be the first image.
The problem is that i need to change the arrow only in the selected item, not in all of them. I have no idea how can I do it with Ionic. Any 'special' method?
Thanks
<ion-item ng-repeat="beac in disp" class="item-icon-right" ng-click="selectedItem=beak">
<b>{{choosen.network}} - {{beac.minor}}</b> • {{beac.viewed}} / {{beac.conf}}
<i class="icon ion-arrow-right-b" ng-show="selectedItem!=beak"></i>
<i class="icon ion-arrow-down-b" ng-show="selectedItem==beak"></i>
Or even like this:
<ion-item ng-repeat="beac in disp" class="item-icon-right" ng-click="selectedItem=beak">
<b>{{choosen.network}} - {{beac.minor}}</b> • {{beac.viewed}} / {{beac.conf}}
<i class="icon" ng-class="{'ion-arrow-down-b': beak==selectedItem, 'ion-arrow-right-b': beak!=selectedItem}"></i>
Hope this helps.
$scope.changeArrow = function(index){
$scope.down = index;
};
and then ng-click="changeArrow($index)"
and then ng-show="down === $index"
Your changeArrow function is probably toggling the down variable which in turn change the arrows for all the items. You can pass the item index to this function to control which arrow will be facing down.
Controller
$scope.selectedItemIndex = -1;
$scope.changeArrow(index) {
$scope.selectedItemIndex = index;
}
Template
<ion-item ng-repeat="beac in disp" class="item-icon-right" ng-click="changeArrow($index)">
<b>{{choosen.network}} - {{beac.minor}}</b> • {{beac.viewed}} / {{beac.conf}}
<i class="icon ion-arrow-right-b" ng-show="$index === selectedItemIndex"></i>
<i class="icon ion-arrow-down-b" ng-show="$index !== selectedItemIndex"></i>

(Meteor) 'click' event doesnt get new value

I get stuck in this case:
I create a list of records in html:
{{#each data}}
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="1"></i>
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="2"></i>
...
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="10"></i>
{{/each}}
I want to everytime I click on each item, it writes "hotel-id" of that item in console log; So, in js I create:
'click .btn-edit-ota': function (event, template) {
var hid = $(event.target).data('hotel-id');
console.log(hid);
}
And it works fine, it shows '1' in the console log when I click the 1st and so on '2' with 2nd, ...
In js, I have an autorun:
Template.myTemp.onRendered(function () {
var self = this;
self.autorun(function (computation) {
... //generate my list here...
}
});
so whenever I change any checkboxs or filters or current page..., the autorun will run and I get a new list.
The problem here is when that autorun runs, and I get a new list.
e.g: now is:
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="11"></i>
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="12"></i>
...
<i class="fa fa-fw fa-pencil-square-o btn-edit-ota" data-hotel-id="20"></i>
I click in the 1st, It shows '1' in console log. :((
It should show '11'. Because the HTML now is: ...data-hotel-id="11">, not ...data-hotel-id="1"> any more.
It must be use the old data/html I think.
Something weirds happened with that 'click' event
$(event.target).data('hotel-id');
It doesnt get a new ID.
Anyone can tell me why this happened?
Many thanks.

Avoid ember to wrap my component

This is my component:
{{#link-to routeName class="list-group-item"}}
<i class="fa {{icon}} fa-fw"></i> {{text}}
{{/link-to}}
Which I use:
<div class="list-group">
{{icon-link routeName="my-account" icon="fa-user" text="Personal details"}}
...
</div>
The expected html is:
<div class="list-group">
<a class="list-group-item" href="xxx">
<i class="fa fa-user fa-fw"></i> Personal details
</a>
...
</div>
But because ember wraps the components in a div, the bootstrap rules do not apply anymore and the list-group has a wrong style.
If I change the component tag to a, and remove link-to from the component template, I loose the flexibility of link-to - and I do not know how to set attributes (href, class) in the containing tag.
It seems I can not use an Ember component for this then? Or is there a way to tellink ember no to wrap my component in a div, or anything else really: in order for the CSS to work, the markup structure must not be modified.
I've not tried this myself but apparently you can create custom link-to components by extending Ember.LinkComponent. Something like this might work...
// app/components/icon-link.js
export default Ember.LinkComponent.extend({
classNames: ["list-group-item"],
icon: null,
text: null,
})
...
// app/templates/components/icon-link.hbs
<i class="fa {{icon}} fa-fw"></i> {{text}}
...
// wherever
{{icon-link 'my-account' icon="fa-user" text="Personal details"}}
Here's a related blog post which may help you also - http://til.hashrocket.com/posts/faef1058c3-inheriting-from-linkcomponent-in-ember-is-amazing

Update icon returned by CSS

In the application I am working on, we can add the following markup for the pictured result
<span class="cell-inner-undefined">
<span title='Not defined' class="status pl-undefined" ></span>
</span>
Inside the relevant CSS we have the following:
.pl-undefined:before {
content: "";
color:#969696;
}
The item assigned to content looks like unicode. Instead of that I want to get the result of the following:
<span class="fa-stack fa-5x">
<i class="fa fa-info-circle fa-stack-1x" style="color:blue" ></i>
<i class="fa fa-ban fa-stack-1x" style="color:red"></i>
</span>
How can I get the class 'pl-undefined' to return the FA icon generated above?
p.s: Adding the fa span in my page displays the desired icon, but I need it to be displayed using the class.
I didn't find any other way of achieving this, other than adding a javascript which will find a <span class="cell-inner-undefined"> and replace it with the fa CSS

Resources