Reputation: 26117
I have multiple Cards in a For loop. In each card, I would like to show and hide content inside the card using a link or a button. I do not have unique Ids to assign each div I want to toggle. Is there a way to do this?
The following code expands or collapses the content in the first card only, even if any "Expand" or "Collapse" button is clicked in any card.
<div *ngFor="let result of results">
<div class="clr-col-lg-12 clr-col-12">
<div class="card">
<div class="card-block">
<div *ngIf="result?.name">
<h3 class="card-title">{{result.name}}</h3>
</div>
<div class="expandCollapse">
<button (click)="toggle($event)">
{{buttonName}}
</button>
</div>
<div class="expandCollapseContent" *ngIf="showRuleContent">
<div *ngIf="result?.cTag">
<h5>C Tag</h5>{{result.cTag}}
</div>
</div>
</div>
</div>
</div>
</div>
Component
public showRuleContent:boolean = false;
public buttonName:any = 'Expand';
toggle($event) {
this.showRuleContent = !this.showRuleContent;
// CHANGE THE NAME OF THE BUTTON.
if(this.showRuleContent)
this.buttonName = "Collapse";
else
this.buttonName = "Expand";
}
Upvotes: 5
Views: 15171
Reputation: 8904
Here is a neat way to hide/show items in a list. You can use template element properties instead of storing something in an array.
Note how it takes advantage of Angular's template variables (#ContentElement).
<ng-container *ngFor="let item of list">
<div #ContentElement></div>
<button (click)="toggle(ContentElement)">Toggle</button>
</ng-container>
// Maybe there are other ways to do this part, here is an example.
// Idea here is to toggle a class.
toggle(e: HTMLElement) {
e.classList.toggle('hidden');
}
.hidden {
display: none;
}
If instead of hiding, you want to remove the element from the DOM:
close(e: HTMLElement) {
e.remove();
}
Upvotes: 2
Reputation: 115222
You can use an array which holds the visible state of each element instead of a single variable.
Template
<div *ngFor="let result of results;let i = index">
<div class="clr-col-lg-12 clr-col-12">
<div class="card">
<div class="card-block">
<div *ngIf="result?.name">
<h3 class="card-title">{{result.name}}</h3>
</div>
<div class="expandCollapse">
<button (click)="toggle(i)">
{{hideRuleContent[i] ? 'Expand' : 'Collapse'}}
</button>
</div>
<div class="expandCollapseContent" *ngIf="!hideRuleContent[i]">
<div *ngIf="result?.cTag">
<h5>C Tag</h5>{{result.cTag}}
</div>
</div>
</div>
</div>
</div>
</div>
Component
public hideRuleContent:boolean[] = [];
public buttonName:any = 'Expand';
toggle(index) {
// toggle based on index
this.hideRuleContent[index] = !this.hideRuleContent[index];
}
Upvotes: 7