22

How do you add a custom column in a mat table.

Such as adding an edit column containing an edit icon with a click event containing the id of the current element.

<div class="example-container mat-elevation-z8">
  <mat-table #table [dataSource]="dataSource">

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Position Column -->
    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
      <mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="weight">
      <mat-header-cell *matHeaderCellDef> Weight </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
    </ng-container>

    <!-- Color Column -->
    <ng-container matColumnDef="symbol">
      <mat-header-cell *matHeaderCellDef> Symbol </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
    </ng-container>
    
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
</div>
1
  • You pasted the wrong plnkr link. Commented Oct 14, 2017 at 17:00

4 Answers 4

36

On your TableBasicExample.ts add

export class TableBasicExample {
  displayedColumns = ['position', 'name', 'weight', 'symbol', 'customColumn1'];
  dataSource = new ExampleDataSource();
}

And in your html file add the column:

<ng-container matColumnDef="customColumn1">
  <mat-header-cell *matHeaderCellDef> Custom Title</mat-header-cell>
  <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
</ng-container>
Sign up to request clarification or add additional context in comments.

3 Comments

Important to note here is the *matHeaderCellDef. It having no argument means that you have no column or key to assign to it and thus you can use it as a custom column e.g. for actions. Not putting it there would raise errors.
Not seeing any difference with *matHeaderCellDef here
Actually I have to add a column on which if we click, it should not affect the checkbox. Could you please suggest
16

Here is the one way to do it. It might help someone down the road.

table.html

    <ng-container matColumnDef="action">
       <th mat-header-cell *matHeaderCellDef> Action </th>
       <td mat-cell *matCellDef>
           <ng-container *ngTemplateOutlet="templateRef"></ng-container>
       </td>
   </ng-container>

table.component

 @Input() templateRef: TemplateRef<any>;

table-parent.html

<app-data-table [dataSource]="dataSource" [templateRef]="template">
   <ng-template #template>
      <button mat-icon-button color="warn">
         <mat-icon>delete</mat-icon>
      </button>
      <button mat-icon-button color="primary">
         <mat-icon>edit</mat-icon>
      </button>
   </ng-template>
</app-data-table>

Hope that saves someone couple hours of search :)

Comments

5

What you are trying to achieve is also made in this package angular4-material-table, which add some structure to allow row insertion, edition and deletion. You have an example to add custom actions columns on this plunkr.

You can define a column with your desired buttons/actions:

<mat-table [dataSource]="dataSource">
    <ng-container matColumnDef="column1"> 
        <mat-header-cell *matHeaderCellDef> column 1 title </mat-header-cell>
        <mat-cell *matCellDef="let row">
            <!-- col 1 -->
        </mat-cell>
    </ng-container> 
    <ng-container matColumnDef="column2"> 
        <mat-header-cell *matHeaderCellDef> column 2 title </mat-header-cell>
        <mat-cell *matCellDef="let row">
            <!-- col 2 -->
        </mat-cell>
    </ng-container>
    <ng-container matColumnDef="actionsColumn">
        <mat-header-cell *matHeaderCellDef>
            <button (click)="createNew()">Create new</button>
        </mat-header-cell>
        <mat-cell *matCellDef="let row">
            <button (click)="edit()">Edit</button>
            <button (click)="cancelOrDelete()">Cancel</button>
        </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns">
    </mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;">
    </mat-row>
</mat-table>

You must include the column in the displayedColumns string array:

displayedColumns = ['column1', 'column2', 'actionsColumn']; 

1 Comment

Hi there plnkr link you shared is not working.
5

To add an extra column for your buttons/actions, you first need to add that column to the displayed columns list in the component:

  displayedColumns: string[] = ['name', 'email', 'phone', 'customColumn'];

and then add an extra column in the html and place your button inside mat-cell:

    <ng-container matColumnDef="customColumn">
      <th mat-header-cell *matHeaderCellDef></th>
      <td mat-cell *matCellDef="let person"> 
          <button mat-button>Edit</button>
      </td>
    </ng-container>

And it's done. It is that easy.

1 Comment

Wildly underrated answer! Thanks, it was super helpful.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.