How do I make one accordion open at a time with an ngFor in the code?
I would like to try inserting an If which indicates that if one accordion is open, the other closes automatically. If I try to put the ngIf in the html, the accordion no longer works and is not shown. What am I doing wrong?
user-detail.component.ts
<mat-accordion >
<mat-expansion-panel
(click)="commentOpen(post.id)">
<mat-expansion-panel-header *ngIf="panelOpenState">
<mat-panel-title>
Self aware panel
</mat-panel-title>
<mat-panel-description>
Currently I am {{panelOpenState ? 'open' : 'closed'}}
</mat-panel-description>
</mat-expansion-panel-header>
<form [formGroup]="commentForm" >
<input matInput type="text" formControlName="email" placeholder="email" #commentEmail required>
<input matInput type="text" formControlName="name" #commentName placeholder="name" required>
<textarea matInput formControlName="body" #commentBody placeholder="Commenta..."></textarea>
<button type="submit" [disabled]="commentForm.invalid"
(click)="onSubmitComment(commentEmail.value, commentName.value, commentBody.value, post.id)">Invia</button>
</form>
<div id="txtdataCommens" *ngFor="let comment of comments">
{{comment.id}}
<br>
{{comment.email}}
<br>
{{comment.name}}
<br>
{{comment.body}}
</div>
</mat-expansion-panel>
</mat-accordion>
user-detail.component.ts
panelOpenState = false;
commentOpen(idPost:any){
this.commentService.postId = idPost
this.getCommentDetailByUser();
this.panelOpenState = !this.panelOpenState
}
CodePudding user response:
Use the expanded
directive to collapse/expand the corresponding panel and keep track of the opened panel index in your component, e.g.
Template:
<mat-accordion >
<mat-expansion-panel
*ngFor="let entry of data; let i = index"
[expanded]="step === i"
(opened)="setStep(i)"
hideToggle
>
<mat-expansion-panel-header>
<mat-panel-title> {{entry.name}} </mat-panel-title>
</mat-expansion-panel-header>
<div>
Some panel content
</div>
</mat-expansion-panel>
</mat-accordion>
Component:
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent {
step = 0;
data = [{ name: "test" }, { name: "test2" }];
setStep(index: number) {
this.step = index;
}
}
Codesandbox example: https://codesandbox.io/embed/angular-material-forked-0yfiye?fontsize=14&hidenavigation=1&theme=dark
CodePudding user response:
use below code snippet wich will work with *ngFor to open one accordion at a time. Here we are using 'expanded' directive with index from ngFor which will set step to open
<mat-accordion >
<mat-expansion-panel [expanded]="step === i" (opened)="setStep(i)" hideToggle *ngFor="let comment of comments; let i = index"
(click)="commentOpen(post.id)">
<mat-expansion-panel-header>
<mat-panel-title>
Self aware panel {{i}}
</mat-panel-title>
<mat-panel-description>
Currently I am
</mat-panel-description>
</mat-expansion-panel-header>
<!-- <form [formGroup]="commentForm" >
<input matInput type="text" formControlName="email" placeholder="email" #commentEmail required>
<input matInput type="text" formControlName="name" #commentName placeholder="name" required>
<textarea matInput formControlName="body" #commentBody placeholder="Commenta..."></textarea>
<button type="submit" [disabled]="commentForm.invalid"
(click)="onSubmitComment(commentEmail.value, commentName.value, commentBody.value, post.id)">Invia</button>
</form> -->
sample form
<div id="txtdataCommens">
{{comment.id}}
<br>
{{comment.email}}
<br>
{{comment.name}}
<br>
{{comment.body}}
</div>
</mat-expansion-panel>
</mat-accordion>
In .TS you need to declare steps variable like given below
step:number = 0;
And add below method in the same .ts file
setStep(index)
{
this.step = index;
}