0

I am working on the Angular Material Table and get the data source dynamically. I want to toggle multiple rows on a row click with expand all rows on a button click outside the table.

I can expand a one row at a time on row click but i want to toggle multiple rows. How can i do that?

Here is the html

<input class="input-form-submit" type="button" value="SHOW ALL DETAIL" (click)="showAllDetail()">

<table mat-table [dataSource]="dataSource" matSort multiTemplateDataRows class="mat-elevation-z8 material-table">

  <ng-container matColumnDef="postedBy">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>By</th>
    <td mat-cell *matCellDef="let element">{{element.first_name}}</td>
  </ng-container>

  <ng-container matColumnDef="postDate">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>
    <td mat-cell *matCellDef="let element">{{element.date | date: 'M/d/yyyy h:mm a'}}
    </td>
  </ng-container>

  <ng-container matColumnDef="balance">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Balance</th>
    <td mat-cell *matCellDef="let element">
      ${{element.balance}}</td>
  </ng-container>

  <ng-container matColumnDef="collected">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Collected</th>
    <td mat-cell *matCellDef="let element">
      (${{element.amountReceived | number : '1.2-2'}})
  </ng-container>

  <ng-container matColumnDef="adjusted">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Adjusted</th>
    <td mat-cell *matCellDef="let element">
      ${{element.adjusted | number : '1.2-2'}}
  </ng-container>

  <ng-container matColumnDef="expandedDetail">
    <td mat-cell *matCellDef="let element; let i = index" [attr.colspan]="displayedColumns2.length">
      <ng-container *ngIf="showDetailTransaction || (selectedRow == element && i)">
        <div class="trans-div">
          <table class="dt-width transaction-expansion" [@detailExpand]="checkExpanded(element) ? 'expanded' : 'collapsed'">
            <ng-container>
              <tr>
                <td>DATA TO EXPAND</td>
              </tr>
            </ng-container>

          </table>

        </div>
      </ng-container>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns2"></tr>
  <tr mat-row *matRowDef="let element; columns: displayedColumns2;" class="transaction-exp-row" [class.transaction-expand-row]="checkExpanded(element)" (click)="onExpandOneRow(element)"></tr>
  <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="transaction-detail-row" style="height: 0px !important;"></tr>
</table>

Here is the ts code

showAllDetail() {
  this.showDetailTransaction = true;
}

checkExpanded(element): boolean {
  let flag = false;
  this.expandedElement.forEach(e => {
    if (e === element) {
      flag = true;
    }
  });
  return flag;
}

onExpandOneRow(element) {
  const index = this.expandedElement.indexOf(element);
  if (index === -1) {
    this.expandedElement.push(element);
  } else {
    this.expandedElement.splice(index, 1);
  }
  this.selectedRow = element;
  this.showHideRow = !this.showHideRow;
}

1 Answer 1

1

For me, the best solution is add a new propertie to dataSource "expanded"

export interface PeriodicElement {
  ...
  expanded?: boolean;
}

Then, when click in tr we change this value

  <tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
      class="example-element-row"
      [class.example-expanded-row]="element.expanded"
      (click)="element.expanded = !element.expanded">
  </tr>

At last you say when is expanded as

<div class="example-element-detail"
           [@detailExpand]="element.expanded ? 'expanded' : 'collapsed'">

For show all you make a function that put the variable expanded of the datasource to true -or false if all are true

showAll() {
    if (this.dataSource.some(x => !x.expanded))
      this.dataSource.forEach(x => (x.expanded = true));
    else 
      this.dataSource.forEach(x => (x.expanded = false));
  }

See the stackblitz

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

Comments

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.