Hi. I have a list of data which uses Accordion in Ionic 6.
I want to have a button that expands all and collapses all the items in accordion so that the I do not have to click each item just to open them to lessen the clicks. How can I achieve this programmatically?
Thank you.
Developers can allow multiple accordions to be open at once with the multiple
property
<ion-accordion-group [multiple]="true" [value]="['first', 'third']">
On button you can toggle accordion and set value
<ion-button (click)="toggleAccordion()">Toggle Accordion</ion-button>
Define function in .ts file
export class ExampleComponent {
@ViewChild('accordionGroup', { static: true }) accordionGroup: IonAccordionGroup;
toggleAccordion = () => {
const nativeEl = this.accordionGroup;
if (nativeEl.value === 'second') {
nativeEl.value = undefined;
} else {
nativeEl.value = 'second';
}
};
}
1 Like
You have to use <ion-accordion-group [value]="valuesOfTheAccordionsThatShouldBeExpanded">
and pass an array of all the values of the accordions (or an empty array if you want to collapse all).
In Angular, you could do something like:
<button (click)="myAccordionGroup.value = ['first', 'second']">
Expand all
</button>
<button (click)="myAccordionGroup.value = []">Collapse all</button>
<ion-accordion-group #myAccordionGroup multiple>
<ion-accordion value="first">
<ion-item slot="header">
<ion-label>First Accordion</ion-label>
</ion-item>
<div slot="content">first</div>
</ion-accordion>
<ion-accordion value="second">
<ion-item slot="header">
<ion-label>Second Accordion</ion-label>
</ion-item>
<div slot="content">second</div>
</ion-accordion>
</ion-accordion-group>
In my case I didn’t want to manually set the accordion values and manage the state of the accordion group like this. I wanted to be able to do something like <button (click)="myAccordionGroup.expandAll()">
, so I created an Angular directive to add this functionality:
import { ContentChildren, Directive, QueryList } from "@angular/core";
import { IonAccordion, IonAccordionGroup } from "@ionic/angular/standalone";
@Directive({
selector: "[appAccordionGroupToggle]",
// add exportAs so you can get a reference to the directive in your template
exportAs: "appAccordionGroupToggle",
standalone: true,
})
export class AccordionGroupToggleDirective {
// get a reference to the ion-accordion instances inside
@ContentChildren(IonAccordion) accordions!: QueryList<IonAccordion>;
// get a reference to the ion-accordion-group instance
constructor(private host: IonAccordionGroup) {}
expand() {
// setting the value of the ion-accordion-group to an array of all the
// ion-accordion values will expand all ion-accordions
this.host.value = this.accordions.map((accordion) => accordion.value);
}
collapse() {
// setting the value of the ion-accordion-group to an empty array will
// collapse all ion-accordions inside
this.host.value = [];
}
}
Now I can simply toggle all items in my template like this:
<button (click)="toggler.expand()">Expand all</button>
<button (click)="toggler.collapse()">Collapse all</button>
<ion-accordion-group appAccordionGroupToggle
#toggler="appAccordionGroupToggle">
<ion-accordion>
<ion-item slot="header">
<ion-label>First Accordion</ion-label>
</ion-item>
<div slot="content">First accordion content</div>
</ion-accordion>
<ion-accordion>
<ion-item slot="header">
<ion-label>Second Accordion</ion-label>
</ion-item>
<div slot="content">Second accordion content</div>
</ion-accordion>
</ion-accordion-group>
Note that there’s no accordion state related stuff in my component. I just need to import the directive:
@Component({
...
standalone: true,
imports: [
...
AccordionGroupToggleDirective,
],
})
export class MyComponent {
}