I am trying to use both regular class attribute and class conditional attribute in an html element below:
<ul *ngIf="showDropdown">
<li class="active" [class.active]="sIndex === x" (click)="dropdownSelect($event.target.value, x)" value="18203">All Groceries</li>
<li [class.active]="sIndex === x" (click)="dropdownSelect($event.target.value, x)" *ngFor='let i of lists; let x = index' value="{{i.id}}">{{i.name}}</li>
</ul>
I have the first li I want to be active but have click attribute which toggles click. Any ideas?
You can use
[ngClass]={"active": sIndex === x}
But in your code you already have the class "active" by default, so nothing will change, always going to have the active class.
explain more, what you want to do.
You're example is looking weird ,
the first li is always active no matter what will happen , and both of li have the same condition that makes them active .
Try this
<ul *ngIf="showDropdown">
<li [class.active]="sIndex === x" (click)="dropdownSelect($event.target.value, x)" value="18203">All Groceries</li>
<li [class.active]="sIndex !== x" (click)="dropdownSelect($event.target.value, x)" *ngFor='let i of lists; let x = index' value="{{i.id}}">{{i.name}}</li>
</ul>
This is the right way to add a class in case its true
[class.active]="sIndex === x"
I figured the answer out. So if you want to have a conditional where active class changes when you click, but want an active class on any element first you do the following:
[ngClass]="{'active': sIndex === x || first}" (click)="dropdownSelect($event.target.value, x)"
add a conditional parameter with your toggle active class on click.
constructor(private api: API, private http: Http) {
this.first = true;
}
you set first to true in in your constructor. then when someone clicks, you put it into function and set it to false;
dropdownSelect(v, x: number) {
this.filter = v;
this.sIndex = x;
this.showDropdown = !this.showDropdown;
this.first = false;
}
Related
In my Home page, I have a search bar and imported three components. my search bar have the ability to search through them but just wondering how can I hide a particular component if a result in not found in that component and only show a component that have a result.
The problem I have right now is, if search result is only found in Application group component then, the attachment and training component is showing me blank (pls check uploaded image below). I just want to hide the components that don't have the result while user is filtering/searching and just show it back the component when a user cancel the search.
I would be really appreciated if I can get help or suggestion on this.
<!-- attachments -->
<div>
<app-attachment [attachments]="entity.attachments"></app-attachment>
</div>
<!-- appgroups -->
<div *ngFor="let entityGroup of entity.entityGroups">
<app-application-group [entityGroup]="entityGroup" [entity]="entity"></app-application-group>
</div>
<!-- Training and Support -->
<div>
<app-training [entity]="entity"></app-training>
</div>
</div>
ngOnInit(): void {
this.searchText$ = this.searchService.searchText
.asObservable()
.pipe(debounceTime(750), distinctUntilChanged())
.subscribe((value) => {
this.filterValue = value;
this.loadApplication(this.entityType, this.entityId);
});
this.collapse = false;
this.expanded = true;
this.route.url.subscribe((_value) => {
this.entityType = BaseEntity.stringToType(_value[0].path);
this.entityId = Number(_value[1].path);
this.loadApplication(this.entityType, this.entityId);
this.populateMeetups(this.entityId);
});
}
loadApplication(entityType: EntityType, entityId: number): void {
this.color = BaseEntity.color(this.entityType);
if (this.entityType && this.entityId) {
// this.filterValue = null;
this.childrenActive = null;
this.pageSize = 999;
this.childrenActive = true; // We want to bring only active children for things that have tables.
}
this.entityService
.getApplicationDetails(
entityId,
entityType,
this.pageSize,
this.childrenActive,
this.filterValue,
)
.subscribe((entity) => {
this.entity = entity;
this.ancestor = this.entity.channels.get(0);
this.entityGroup = this.entity.entityGroups.filter(
(r) => r.entityType === EntityType.Application,
);
this.entity.attachments = this.entity.attachments.filter((app) => {
return app.name.toLowerCase().includes(this.filterValue.toLowerCase());
});
});
}
click here to view my screenshot
Use *ngIf to remove stuff from the DOM you don't want to show. For example:
<ng-container *ngIf="entity.attachments?.length">
<div>
<app-attachment [attachments]="entity.attachments"></app-attachment>
</div>
</ng-container>
Or hide it with css:
<div [ngClass]="entity.attachments?.length ? 'show' : 'hide'">
<app-attachment [attachments]="entity.attachments"></app-attachment>
</div>
and the css:
.hide {
visibility: hidden;
}
You may want to consider placing the *ngIf inside the child component instead of the parent.
Try to use ngIf by checking the length of the search result instead of creating a new variable. Also use else block to display no result found as shown below
Show result here
No result found .
I am using Angular CLI. Actually, I have a menu list. And I would like to change the background color of <li> when I click on it.
I send id to functionchangeColor(). But the problem is I am getting menuButton as null. Please help me to do so.
.html
<ul>
<li id="menu_btn" (click)="changeColor()" >
</li>
<li id="menu_btn" (click)="changeColor()">
</li>
<ul>
.ts:
changeColor() {
let menuButton = document.getElementById("menu_btn");
menuButton.style.backgroundColor = '#816587';
}
The more angular way to do this is define your menu list in an array
// component.ts
menuList = [
{
name: 'Option 1',
isSelected: false
},
{
name: 'Option 2',
isSelected: false
}
];
Then use an ngFor to render the list and use ngClass + each menu items isSelected flag to toggle a selected class.
// component.html
<ul>
<li *ngFor="let menuItem of menuList" (click)="changeColor(menuItem)"
[ngClass]="{'selected': menuItem.isSelected}">
{{menuItem.name}}
</li>
</ul>
// component.css
.selected{
background-color: #816587;
}
Now have your changeColor method handle the toggling of the isSelected flag
changeColor(menuItem){
// toggle off all selected menu items
this.menuList.forEach(item => {
if(item.isSelected){
item.isSelected = false;
}
});
// select clicked menu item
menuItem.isSelected = true;
}
This way angular is handling all of the DOM manipulation. Here is plnkr demonstrating this functionality (https://plnkr.co/edit/NEnzKZ84M85mErYGLE1Y?p=preview)
You can use ngStyle to do this:
<li id="menu_btn" (click)="myStyle = {'background-color': #816587}" [ngStyle]="myStyle">
We are creating a way to filter in our jobs portal.
{{#rl-dropdown tagName="ul" class="dropdown-menu" closeOnChildClick="li"}}
<li {{action 'filterWith' department 'all'}}>
All
</li>
<li active=true {{action 'filterWith' department 'intern'}}>
Intern
</li>
<li {{action 'filterWith' department 'newgrad'}}>
New Grads
</li>
<li {{action 'filterWith' department 'entry'}}>
Entry Level
</li>
<li {{action 'filterWith' department 'senior'}}>
Senior
</li>
{{/rl-dropdown}}
When a user clicks a <li>, it will call the function filterWith which filters either/or (AKA exactly one filter is applied at any time). We want whichever filter is clicked to be highlighted a different color from the rest.
Implementing this has been very difficult because we want to do it in a way that doesn't use jQuery (we have been having trouble with mixing jQuery and Ember together). We might be able to do it just with Bootstrap to do it if we knew how to.
Edit:
This is my Ember Controller (AKA where filterWith is defined).
export default Ember.Controller.extend({
department: 'all',
level: 'all',
filteredPosts: Ember.computed('level', function() {
var emberCont = this;
return this.get('model').filter(function(item){
var lvl = emberCont.get('level');
// This should be refactored somehow
if(lvl == 'all') {
return true;
}
else if (lvl == item.get('level')) {
return true;
}
return false;
});
}),
actions: {
filterWith(dept, lvl) {
this.set('department', dept);
this.set('level', lvl);
}
}
});
I filter by two variables (level and filter). Department currently doesn't do anything so I suggest ignoring it.
Probably the action filterWith somehow should store the current filter value. Next you can the eq helper from ember-truth-helpers to do something like class="{{if (eq currentFilter 'intern') 'active'}}", which will give you the active class on the current filter. The rest is simple CSS.
Checkout this twiddle for a working demonstration.
The other thing you could do is to generate your filters dynamically, and then attach a boolean telling which one is active. This is a solution without a helper.
I want to add a class to an element if the title of the page includes "Home".
Currently, I use this:
<li data-bind="css: { 'active': function(){return document.title.indexOf('Home') > -1;}}">
However this does not work, this function does not get executed...
How do I make this work?
Knockout wraps the value in a computed function in a way that resembles this:
Input: "yourClassName": whateverYouPutIn
Output: "yourClassName": ko.computed(function() { return whateverYouPutIn; })
In your case, you put in a function, which will result in a "truethy" value setting the active class. You can fix this by:
Option 1 (quick): Don't wrap it in a function
<li data-bind="css: {
'active': document.title.indexOf('Home') > -1
}"></li>
Option 2 (not recommended): Fix the typo (funciton) and call the function
<li data-bind="css: {
'active': (function() {
return document.title.indexOf('Home') > -1;
}())
}"></li>
Option 3: Add these kinds of properties to your viewmodel
var vm = {
// set when VM is initialized
isActive: document.title.indexOf("Home"),
// if you want to check the title during data-binding
isActiveDuringBind: function() {
return document.title.indexOf("Home");
}
}
With either
<li data-bind="css: {'active': isActive }"></li>
or
<li data-bind="css: {'active': isActiveDuringBind() }"></li>
Note that using the DOM api outside of custom bindings is considered "bad practice"... But in this case I guess you can get away with it...
Note that because there are no observable values being used, your class will not toggle when you change document.title.
I am trying to add the class by ng-class in my app.
I have something like
html
<li ng-repeat="item in items"
ng-click="getItem(item)"
ng-class="{shine : item.isPick}" // shine class will make the font color change to red
>{{item.name}}
</li>
In my controller
$scope.getItem = function(item) {
$scope.items.forEach(function(item){
item.isPick = false; // remove all the items that have shine class
})
item.isPick = true; // adding the shine class back
}
Basically I want to remove every other 'shine' class except the selected item when user clicks it. My codes above work but I am thinking there is a better way to do it instead of looping all the items. Can someone help me about it? Thanks a lot!
Use the $index in the repeater, and add the class when that index is selected:
<li ng-repeat="item in items"
ng-click="getItem($index)"
ng-class="{shine : activeIndex == $index}"
>{{item.name}}
</li>
$scope.getItem = function(index) {
$scope.activeIndex = index;
}