Search code examples
htmlangularangular-materialangular-material-table

Angular Material Table dynamic columns


I have created mat-table component which generate dynamic columns by data which I pasted, but without Action icons.

<table mat-table [dataSource]="data" class="mat-elevation-z8">

  <ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
    <th mat-header-cell *matHeaderCellDef>{{ item.header }}</th>
    <td mat-cell *matCellDef="let element">{{ element[item.columnDef] }}</td> 
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>

Data are pasted by Input() from another component.

columns: Column [] = [
  {columnDef: 'faculty_id', header: 'ID'},
  {columnDef: 'faculty_name', header: 'Faculty'},
  {columnDef: 'faculty_description', header: 'Description'},
  {columnDef: 'action', header: 'Actions', actions: [
    {type: tableActionsType.Edit, icon: 'edit', matTooltip: 'Edit'},
    {type: tableActionsType.Delete, icon: 'delete', matTooltip: 'Delete'}
  ]}
];

I need to check in this loop *ngFor="let item of columns; when item.columnDef === 'action' and render mat-icon.

<ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
  <th mat-header-cell *matHeaderCellDef>{{ item.header }}</th>
  <td mat-cell *matCellDef="let element">

    // if item.columnDef == 'action' then mat-icon
    // else {{ element[item.columnDef] }}

    <mat-icon aria-hidden="false" aria-label="edit" *ngFor="let icon of item.actions" [matTooltip]="icon.matTooltip" (click)="check()">{{icon.icon}}</mat-icon>

  </td>
</ng-container>

I want to generate a column Actions with icons.


Solution

  • So I came up with this decision. And it works fine for me.

    <table mat-table [dataSource]="dataSource"  class="mat-elevation-z8" matSort>
      <ng-container [matColumnDef]="item.columnDef" *ngFor="let item of columns; let i = index">
        <th mat-header-cell *matHeaderCellDef mat-sort-header [disabled]="item.columnDef=='action'? true : false ">{{ item.header }}</th>
      
         <ng-container *ngIf="!item.actions"> // *if column is not the action column then render normal column
           <td mat-cell *matCellDef="let element; let i = index">{{ item.header =='ID' ?  matPaginator.pageSize * matPaginator.pageIndex + i + 1 : element[item.columnDef] }}</td>
         </ng-container>
      
         <td mat-cell *matCellDef="let element" class="action-link">
           // *rendering actions in the action column for instance it can be edit or delete
           <mat-icon aria-hidden="false" [attr.aria-label]='action.aria_label' *ngFor="let action of item.actions"  [matTooltip]="action.matTooltip" (click)="getEvent(action,element)">{{action.icon}}</mat-icon>
         </td>
      </ng-container>
    
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
    </table>