Home > Software engineering >  Angular Material expansion panel open fired by radio button
Angular Material expansion panel open fired by radio button

Time:03-15

I have a scenario where I'm trying to use a Material radio button click event to trigger the opening of an associated expansion panel with a mat-accordion control.

The ultimate goal is for the user to click on the radio button, showing the radio state as "checked" and opening the panel containing the selected radio button. Currently, the click event is properly setting the underlying step value, but the panel itself is not being expanded.

Here's the code for the accordion component:

<mat-accordion multi hideToggle>
  <mat-expansion-panel id="panel1" [expanded]="step === 0">
    <mat-expansion-panel-header>
      <mat-panel-title>
        <mat-radio-button name="multi-accordion" id="set-step-0" (click)="setStep(0)">
          <span>Panel 1</span>
        </mat-radio-button>
      </mat-panel-title>
    </mat-expansion-panel-header>
    Panel 1 content
  </mat-expansion-panel>
  <mat-expansion-panel id="panel2" [expanded]="step === 1">
    <mat-expansion-panel-header>
      <mat-panel-title>
        <mat-radio-button name="multi-accordion" id="set-step-1" (click)="setStep(1)">
          <span>Panel 2</span>
        </mat-radio-button>
      </mat-panel-title>
    </mat-expansion-panel-header>
    Panel 2 content
  </mat-expansion-panel>
  <mat-expansion-panel id="panel2" [expanded]="step === 2">
    <mat-expansion-panel-header>
      <mat-panel-title>
        <mat-radio-button name="multi-accordion" id="set-step-2" (click)="setStep(2)">
          <span>Panel 3</span>
        </mat-radio-button>
      </mat-panel-title>
    </mat-expansion-panel-header>
    Panel 3 content
  </mat-expansion-panel>
</mat-accordion>

Here's the .ts file that I'm using to do the work:

export class AccordionComponent implements OnInit {
  step = -1;

  constructor() { }

  ngOnInit(): void {
  }

  setStep(index: number) {
    if (index == this.step) { return; }
    console.log('Step before setting index: ', this.step);
    this.step = index;
    console.log('Step after setting index: ', this.step);
  }
}

I don't understand why the value that's being set properly by the click event (as evidenced by the console.log statements) is not being picked up the binding on the [expanded] ="step === n" on the panel itself.

CodePudding user response:

The condition [expanded]="step === 0" is right but MatExpansionPanel has a behavior that seems to override and toggle the expanded attribute upon click on the MatExpansionPanel, which seems logical for an accordion.

The only solution I found in order to disable this behavior is by adding [disabled]="true" on each <mat-expansion-panel> element :

<mat-expansion-panel id="panel2" [disabled]="true" [expanded]="step === 2">

Working StackBlitz here

CodePudding user response:

Since the ExpansionPanel behavior is overriding the radio button, you might want to just use radio buttons with a div that conditionally shows if the corresponding radio button is clicked.

Working StackBlitz here

  • Related