Open the first attached expansion panel in an Angular Material accordion
Solution 1
You can use first
variable, I made an stackblitz, you can see here.
You can do as this way:
<mat-accordion class="example-headers-align">
<mat-expansion-panel *ngFor="let item of [1,2,3]; first as isFirst" [expanded]="isFirst">
<mat-expansion-panel-header>
<mat-panel-title> {{item}} </mat-panel-title>
</mat-expansion-panel-header>
{{item}}
</mat-expansion-panel>
</mat-accordion>
You can see here the use of the *ngFor
variables for more information.
Solution 2
Have you tried using the ngFor "first" local variable? In this way:
<mat-accordion>
<mat-expansion-panel *ngFor="let elem of elements; let isFirst = first" [expanded]="isFirst">
<!--- Something Here --->
</mat-expansion-panel>
</mat-accordion>
Related videos on Youtube
Aaron Hazelton
Updated on September 22, 2021Comments
-
Aaron Hazelton over 2 years
Obviously you can use the input
expanded
on an Angular Material expansion panel to default a particular panel to be opened upon loading. However, I have an accordion where all of the expansion panels are generated dynamically, and all are optional, but I would like for the first panel to be opened.I could go through each of my
ngFor
s that use templates to generate the panels to see if it exists and then on the first index add the attribute, but there are several loops that pull in templates and it seems messy. I would like to be able to grab some property from themat-accordion
after the view has completed to see which is the first one attached to the accordion and add the attribute, but it looks like it isn't possible. Anyone know if there is some way to do this? -
Aaron Hazelton over 5 yearsGood point, I forgot about isFirst and was going to use the index, but that would still mean I have to do needless if checks because as I mentioned there are multiple ngFors and they are all optional, so I have no way of knowing which ones will appear first in the DOM. That's why I was hoping for a way to get the panels from the accordion component directly. Guess that's not possible. Thanks for the input!
-
Aaron Hazelton over 5 yearsThanks for the input, see comment above.
-
Kalamarico over 5 yearsSo, you have 1 mat-accordion and inside you have some *ngFor applied to a mat-expansion-panel. Is that right? (1 accordion and inside X mat-expansion-panels)
-
Kalamarico over 5 yearsIf I'm right, have you consider to have only one mat-expansion-panel with *ngFor and use the object iterated in the ngFor for your purpose? I'm saying, if you are doing "let item in myObject" inside ngFor, you can "customize" myObject with all the panels items, instead of use several panel objects and write more than one ngFor.... Maybe you can't do that, if you can add a stackblitz example could be better to help
-
Aaron Hazelton over 5 yearsIts a pretty complex config object and everything on page is getting built from it. Reason I'm doing that is that the configs can differ greatly, so I'm using
ng-container
s to see if a certain property of the object exists and if so, then using another container to project my template with anngFor
. Since each of these (all optional) objects are all handled differently, there are multiple templates, too. I could add anotherngFor
as the parent to all of this stuff, but it would be another layer of complexity that would be unnecessary. Not a big deal, will add it if they really want it. -
Kalamarico over 5 yearsI understand, another choice I'm thinking is, you can create a custom directive, and use it in the mat-expansion-panel with ngFor. In that directive you can use a static counter and set a ++ the counter when it's rendered, so, the expanded attr will set to true when that counter is the first... If I can I will show an example
-
Aaron Hazelton over 5 yearsGood idea. I'll see how 'must have' this is first. Thanks!
-
Kalamarico over 5 yearsYou can use a static class for create inside the counter, and import it in the directive (and it will use it to sum) and import also in the component (for use it in the template) I hope solve your problem, if you have problems, comment again! ;)