0

In Angular, I want tu use a Material table with expandables rows.

table-tree.html

<table
  mat-table
  [dataSource]="dataSource"
  multiTemplateDataRows
  class="mat-elevation-z8"
>
  <ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
    <th mat-header-cell *matHeaderCellDef>{{column}}</th>
    <td mat-cell *matCellDef="let element">
      <tr>{{element.creationDate}}</tr>
      <tr>{{element.requestId}}</tr>
    </td>
  </ng-container>

  <ng-container matColumnDef="expandedDetail">
    <td
      mat-cell
      *matCellDef="let element"
      [attr.colspan]="columnsToDisplay.length"
    >
      <div
        class="example-element-detail"
        [@detailExpand]="element == expandedInfo ? 'expanded' : 'collapsed'"
      >
        <div class="example-element-position">{{element.creationDate}}</div>
        <div class="example-element-description">
          {{element.serialNumberProductRefToSupply}}
        </div>
        <div class="example-element-description">
          {{element.serialNumberOriginSupplyToDestination}}
        </div>
      </div>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
  <tr
    mat-row
    *matRowDef="let element; columns: columnsToDisplay;"
    class="example-element-row"
    [class.example-expanded-row]="expandedInfo === element"
    (click)="expandedInfo = element"
  ></tr>
  <tr
    mat-row
    *matRowDef="let row; columns: ['expandedDetail']"
    class="example-detail-row"
  ></tr>
</table>

table-tree.ts

import { Component } from '@angular/core';
import {
  animate,
  state,
  style,
  transition,
  trigger
} from '@angular/animations';

@Component({
  selector: 'table-tree',
  styleUrls: ['table-tree.css'],
  templateUrl: 'table-tree.html',
  animations: [
    trigger('detailExpand', [
      state(
        'collapsed',
        style({ height: '0px', minHeight: '0', display: 'none' })
      ),
      state('expanded', style({ height: '*' })),
      transition(
        'expanded <=> collapsed',
        animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
      )
    ])
  ]
})
export class TableTree {
  dataSource = MoveOrderData;
  columnsToDisplay = [
    'Creation Date',
    'Request ID',
    'Issue',
    'Request Type',
    'Managed by',
    'Product ref to supply',
    'Origin supply to Destination'
  ];
  
  rowsToDisplay = [
    'creationDate',
    'requestId',
    'issue',
    'requestType',
    'managedBy',
    'serialNumberProductRefToSupply',
    'serialNumberOriginSupplyToDestination'
  ];
  expandedInfo: MoveOrderAuthorizations;
}

export interface MoveOrderAuthorizations {
  creationDate: string;
  requestId: number;
  issue: string;
  requestType: string;
  managedBy: string;
  serialNumberProductRefToSupply: string;
  serialNumberOriginSupplyToDestination: string;
}

const MoveOrderData: MoveOrderAuthorizations[] = [
  {
    creationDate: `01/01/2021`,
    requestId: 139322,
    issue: ``,
    requestType: `Evacuation`,
    managedBy: `AGV`,
    serialNumberProductRefToSupply: `ML132345XO1211321AND11432001`,
    serialNumberOriginSupplyToDestination: `SA-11EOL-LN001`
  },
  {
    creationDate: `01/01/2021`,
    requestId: 139323,
    issue: `Destination not found`,
    requestType: `Supply`,
    managedBy: `AGV`,
    serialNumberProductRefToSupply: `ML132345XO1211321AND11432002`,
    serialNumberOriginSupplyToDestination: `RE-11WIP-11E03`
  }
];

In table-tree.ts, there are 2 arrays with columns names and rows infos.

  columnsToDisplay = [
    'Creation Date',
    'Request ID',
    'Issue',
    'Request Type',
    'Managed by',
    'Product ref to supply',
    'Origin supply to Destination'
  ];
rowsToDisplay = [
    'creationDate',
    'requestId',
    'issue',
    'requestType',
    'managedBy',
    'serialNumberProductRefToSupply',
    'serialNumberOriginSupplyToDestination'
  ];

The 1st array is used to display columns names and it works. But I can't display info in each column. All info are in the same. I'm closed to succeed but I can't see what's wrong with my code. You can go and see the table on Stackblitz > https://stackblitz.com/edit/tab-tree?file=main.ts

Thanks :)

bengabo
  • 53
  • 1
  • 8
  • The reason why you are seeing the same data repeating is these lines {{element.creationDate}} {{element.requestId}} . You are supplying same data for two properties but not displaying according to columns. I don't know if you really need row definition here - it looks the same as the column definition. This post can be helpful to you: https://stackoverflow.com/questions/49868019/angular-material-table-dynamic-columns-without-model – usalin Jul 07 '21 at 14:47
  • Thanks for the link Usalin, it's really helpful – bengabo Jul 08 '21 at 09:18

1 Answers1

0

I think you want to use your datasource field names as your column names. I would rename rowsToDisplay to columnsToDisplay and then create a columnNames object:

  columnsToDisplay = [
    'creationDate',
    'requestId',
    'issue',
    'requestType',
    'managedBy',
    'serialNumberProductRefToSupply',
    'serialNumberOriginSupplyToDestination'
  ];

  columnNames = {
    creationDate: 'Creation Date',
    requestId: 'Request ID',
    issue: 'Issue',
    requestType: 'Request Type',
    managedBy: 'Managed by',
    serialNumberProductRefToSupply: 'Product ref to supply',
    serialNumberOriginSupplyToDestination: 'Origin supply to Destination'
  };

Then in your template, update to use the columnsToDisplay array to pull the correct values from your datasource:

  <ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
    <th mat-header-cell *matHeaderCellDef>{{columnNames[column]}}</th>
    <td mat-cell *matCellDef="let element">
      {{element[column]}}
    </td>
  </ng-container>

https://stackblitz.com/edit/tab-tree-muxipv?file=app%2Ftable-tree.html

robbieAreBest
  • 1,601
  • 14
  • 16