2
votes

I recently added the Angular Material accordion component in my angular project. In the API they use the examples provided for automatically closing the panel: https://material.angular.io/components/expansion/examples <-- look here (doing (opened) = panelStateOpen in the template and specifying the boolean in the component)

I did this but because I'm looping through the information of menuItems, have two components, and then injecting my expansion panel, the panelOpenState isn't correct.

Right now, I have

<mat-accordion *ngFor="let menuItem of menuItems">
  <confmenu menuItem={{menuItem}}></confmenu>
</mat-accordion>

In my parent template, and in my confmenu (child template):

<mat-expansion-panel (opened)="panelOpenState=true" (closed)="panelOpenState=false">
  <mat-expansion-panel-header>
    <mat-panel-title>
      {{menuItem}}
    </mat-panel-title>
    <mat-panel-description>
      {{menuDescription}}
    </mat-panel-description>
  </mat-expansion-panel-header>

  <mat-form-field>
    <mat-select (change)="selectConfig($event.value)">
      <mat-option *ngFor="let option of menuOptions" [value]="option" (click)="selectConfig(option)">
        {{option}}
      </mat-option>
    </mat-select>
  </mat-form-field>             
</mat-expansion-panel>

in the child's component I have panelOpenState = false;

the ts as a whole is

/** @title Basic menu */
@Component({
  selector: 'confmenu',
  templateUrl: './confmenu.component.html',
  styleUrls: ['./confmenu.component.scss']
})
export class ConfigurationMenu implements OnInit, OnDestroy {
  @Input() menuItem: string;
  panelOpenState = false;
  constructor() {}

  ngOnInit() { 
  }

  ngOnDestroy() {
    //blank for now
  }

  selectConfig(value:string){
    this.selectedConfig = value;
    this._menuService.changeSelectedConfig(this.selectedConfig);
    this._menuService.populateSelectedConfigConfigurations(this.selectedConfig);
  }
}

Any ideas on how to make it so that the panels close on click of another panel? Right now, they are all staying open upon clicking another.

2
can you show TS file of child component - LALIT KANTA DIBYADARSHAN
@LALITKANTADIBYADARSHAN i edited it - Emily
Are you getting any error in console - LALIT KANTA DIBYADARSHAN
@LALITKANTADIBYADARSHAN , no, i'm not. i don't think that's the issue. i think it's because i have multiple of them, they're in a for loop - Emily

2 Answers

2
votes

Most simple autoclosing with list of items to represent in mat-expansion panel - is to store current opened id of panel item.

component.html

<ng-container *ngFor="let item of items">
<mat-expansion-panel 
  [expanded]="item.id === currentOpenedItemId" 
  (opened)="handleOpened(item)"
>
</ng-container>

component.ts

...
currentOpenedItemId: number;

public handleOpened(item): void { 
  this.currentOpenedItemId = item.id;
}

also you can set initial value while you got data - to open first panel

1
votes

use this sample https://stackblitz.com/angular/olmedrdbamo?file=src%2Fapp%2Fexpansion-steps-example.ts use *ngFor index for the 'step'

<mat-accordion *ngFor="let menuItem of menuItems; let index = index">
                <confmenu menuItem={{menuItem}} [index]="index"></confmenu>
  </mat-accordion>

add @Input() index: number; to the component

and you can adjust that sample like this

 <mat-expansion-panel [expanded]="step === index" (opened)="setStep(index)" hideToggle>