Implementing a Minimal Angular Material Data Table With Drag and Drop | Task

Ole Ersoy
Mar - 01  -  2 min

Scenario

Building on our previous minimal data table adding drag and rop:

Approach

Imports

In addition to the modules already in place in the Add the DragDropModule

import { DragDropModule } from "@angular/cdk/drag-drop";

Rememer to also add it to app.module.ts.

Templating

Add the cdkDropList directive to mat-table and add the cdkDrag directive to mat-row.

On mat-table set the [cdkDropListData] property to dataSource.data like this:

[cdkDropListData]="dataSource.data"

Also on mat-table register a cdkDropListDropped event listener:

 (cdkDropListDropped)="onListDrop($event)"
   

The implementation of onListDrop in app.component.ts looks like this:

  onListDrop(event: CdkDragDrop<Todo[]>) {
    console.log("Logging drop");
    console.log(this.todos);
    // Swap the elements around
    moveItemInArray(
      event.container.data,
      event.previousIndex,
      event.currentIndex
    );
  }

This is the full template:

<div style="width: 20rem; margin: 2rem;">
  <mat-table
    (cdkDropListDropped)="onListDrop($event)"
    [cdkDropListData]="dataSource.data"
    cdkDropList
    class="mat-elevation-z8"
    [dataSource]="dataSource"
  >
    <ng-container matColumnDef="id">
      <mat-header-cell *matHeaderCellDef>ID</mat-header-cell>
      <mat-cell *matCellDef="let row;">{{row.id}}</mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"> </mat-header-row>
    <mat-row cdkDrag *matRowDef="let row; columns: displayedColumns"></mat-row>
  </mat-table>
</div>

Demo