The collapse and expand functionality mirrors the approach used in the response to the question posed in How can I expand multiple rows in a Mat Table by clicking on a row in Angular?.
Key Concepts (TL;DR)
- Utilize the
toggleElement
function to add element
to expandedElement
.
- Use the
isExpanded
function to determine if element
exists in expandedElement
.
- Display the element (expanded/collapsed) based on the outcome of
isExpanded
.
PROBLEM SOLVING
Previous Approach
<div class="example-element-detail" *ngIf="element.addresses?.data.length" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<div class="inner-table mat-elevation-z8" *ngIf="expandedElement">
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;" [class.example-element-row]="element.addresses?.data.length"
[class.example-expanded-row]="expandedElement === element" (click)="toggleRow(element)">
</tr>
By adding the element
to expandedElements
to indicate an expanded state, you must ensure the element is present in expandedElements
by using isExpanded(element)
.
Updated Approach
<div class="example-element-detail" *ngIf="element.addresses?.data.length" [@detailExpand]="isExpanded(element)">
<div class="inner-table mat-elevation-z8" *ngIf="isExpanded(element)">
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;" [class.example-element-row]="element.addresses?.data.length"
[class.example-expanded-row]="isExpanded(element)" (click)="toggleRow(element)">
</tr>
.component.ts
export class TableExpandableRowsExample {
...
expandedElements: any[] = [];
...
toggleRow(element: User) {
element.addresses && (element.addresses as MatTableDataSource<Address>).data.length
? this.toggleElement(element)
: null;
this.cd.detectChanges();
this.innerTables.forEach((table, index) => (table.dataSource as MatTableDataSource<Address>).sort = this.innerSort.toArray()[index]);
}
isExpanded(row: User): string {
const index = this.expandedElements.findIndex(x => x.name == row.name);
if (index !== -1) {
return 'expanded';
}
return 'collapsed';
}
toggleElement(row: User){
const index = this.expandedElements.findIndex(x => x.name == row.name);
if (index === -1) {
this.expandedElements.push(row);
} else {
this.expandedElements.splice(index, 1);
}
}
}
See Sample Solution on StackBlitz