0

I have created a nested mat-table grid using Angular Material. But currently only 1 row gets expanded at a time. I want to add a feature so that multiple rows can be expanded at a time, without the previous one getting collapsed.

Working Stackblitz link for Nested Table - https://stackblitz.com/edit/angular-nested-mat-table

Tried pushing elements to ExpandedElement Array but that didn't work much -

const index = this.expandedElements.findIndex(x => x.name == row.name);
if (index === -1) {
  this.expandedElements.push(row);
} else {
  this.expandedElements.splice(index, 1);
}

Can anyone help me on how to add multiple row expansion in this?

1 Answer 1

2

The expand/collapse logic is quite similar as in the answer for How to expand multiple rows in a Mat Table on clicking of a row in Angular?.

Concepts (TL;DR)

  1. toggleElement function to Add element to expandedElement.
  2. isExpanded function to Check element is existed in expandedElement.
  3. Display element (is expanded/collapsed) with isExpanded.

SOLUTION

Previous

<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>

As the element is added into expandedElements to represent it is expanded, thus you need to check whether the element is in the expandedElements with isExpanded(element).

Latest

<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);
    }
  }
}

Sample Solution on StackBlitz

Sign up to request clarification or add additional context in comments.

1 Comment

Will it be possible to create a third grid inside the addresses grid ? @yong

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.