Expand and collapse table rows in nested Material table are having issue when clicking rows in Angular

65 Views Asked by At

I want to expand and collapse table row which is nested in a material table and data is completely dynamic.

On click of sub row it's not expanding and collapsing outer row which is unexpected. How to write proper click event or method which doesn't affect other rows?

I have added picture of dummy screen which is expected: enter image description here

<div class="container">
  <table mat-table [dataSource]="dataSource" multiTemplateDataRows class="mat-elevation-z8">
    <ng-container [matColumnDef]="column" *ngFor="let column of displayedColumns | async;" >
      <th mat-header-cell *matHeaderCellDef class="text-Capitalise" [ngClass]=" column== 'subSection'?'noD':'disp' ">
        {{column && 
        column=='executionId'?'': column && 
        column=='createdBy'?'Created By': column && 
        column=='createdTs'?'Created Date': column && 
        column=='actualsMonth'?'Actual Month': column
        }}
      </th>
      <td mat-cell *matCellDef="let element;"
        [ngClass]="column== 'title'?'title-col':'disp' &&  
        column== 'description'?'description-col':'disp' &&  
        column== 'tags'?'tags-col':'disp' &&  
        column== 'subSection'?'noD':'disp'
        ">
       
        <span *ngIf="column=='executionId'">
          <mat-radio-button color="primary"></mat-radio-button>
        </span>
        <span *ngIf="column=='createdTs'">
          {{ element.section[column] | date  }}
        </span>
        <span class="section-head-text" matTooltip="{{element.section[column]}}">
          {{ element.section[column] && 
          column=='executionId'?'': element.section[column] &&
          column=='tags'?'': element.section[column]&&
          column=='createdTs'?'': element.section[column]
          }}
        </span>

        <span class="test-mat-chips" *ngIf="column=='tags'">
          <mat-chip-listbox>
            <span *ngFor="let symbols of element.section.tags">
              <mat-chip>{{symbols}} </mat-chip>
            </span>
          </mat-chip-listbox>
        </span>
      </td>
    </ng-container>

    <ng-container matColumnDef="expand">
      <th class="expand-column" *matHeaderCellDef aria-label="row actions">
        <button mat-icon-button aria-label="expand row" name='toggleButon'
        (click)="toggle(); $event.stopPropagation()">
        <mat-icon *ngIf="!allRowsExpanded">keyboard_arrow_down</mat-icon>
        <mat-icon *ngIf="allRowsExpanded">keyboard_arrow_up</mat-icon>
      </button>
      </th>
      <td class="expand-column" mat-cell *matCellDef="let element">
        <button mat-icon-button aria-label="expand row"
          (click)="(element.expanded = !element.expanded); $event.stopPropagation()">
          <mat-icon *ngIf="!element.expanded">keyboard_arrow_down</mat-icon>
          <mat-icon *ngIf="element.expanded">keyboard_arrow_up</mat-icon>
        </button>
      </td>
    </ng-container>

    <ng-container matColumnDef="expandedDetail">
      <td class="sub-grid-box" mat-cell *matCellDef="let element"
        [attr.colspan]="displayedColumnsWithExpand.value.length">

        <div *ngFor="let group of element.section.subSection ">
          <button class="grp-btn" mat-icon-button aria-label="expand row"
            (click)="(element.expanded = !element.expanded);$event.stopPropagation() ">
            <mat-icon *ngIf="!element.expanded">keyboard_arrow_down</mat-icon>
            <mat-icon *ngIf="element.expanded">keyboard_arrow_up</mat-icon>
          </button>
          <mat-card class="groupBy collapsible-group">
            <mat-card-content>
              {{group.groupBy.value}}
            </mat-card-content>
          </mat-card>

          <ng-container>
            <!-- {{group.groupBy.subSection | json}} -->
            <div *ngFor="let insgroup of group.groupBy.subSection"
              [@detailExpand]="(element.expanded)? 'expanded' : 'collapsed'" [hidden]="!element.expanded">
              <span class="collapsible-group-data"> {{insgroup.groupBy.value}}</span>
              <div>
                <app-sub-comp [gridData]="insgroup.groupBy.subSection"
                  [displayedColumns]="displayedColumnsWithExpand | async"></app-sub-comp>
              </div>
            </div>
          </ng-container>
        </div>
      </td>
    </ng-container>

    <ng-container>
      <tr mat-header-row *matHeaderRowDef="displayedColumnsWithExpand | async"></tr>
    </ng-container>
    <tr mat-row *matRowDef="let element; columns: displayedColumnsWithExpand | async; " class="element-row"
      [class.expanded-row]="element.expanded" (click)="toggleRow(element)">
    </tr>
    <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
  </table>
</div>
1

There are 1 best solutions below

0
Ale_Bianco On BEST ANSWER

You can add a method in your component to handle the click event on the main row

  toggleRow(element: any) {
    element.expanded = !element.expanded;
  }

and modify the template to use the method when a row is clicked

<tr mat-row *matRowDef="let element; columns: displayedColumnsWithExpand | async; " class="element-row"
  [class.expanded-row]="element.expanded" (click)="toggleRow(element)">
</tr>