Search code examples
angularangular-cdk-drag-drop

cdkDropListDropped="drop($event)" is not firing, mat table with datasource


This is the situation I have, I need to make a column drag n' drop functionality using mat-table and cdkDragDrop from Angular (working with Angular 8).

Here's what I have so far.

Inside a component.html I have:

<mat-table cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)" [dataSource]="dataSource">

  <ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.name">

    <mat-header-cell *matHeaderCellDef cdkDrag cdkDragLockAxis="x">
      {{column.title}}
    </mat-header-cell>

    <mat-cell *matCellDef="let element">{{ element[column.name] }}</mat-cell>

  </ng-container>

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

and inside a component.ts I have:

export class TestClass implements OnInit {
  displayedColumns = ['id', 'firstName', 'lastName', 'email', 'phoneNumber', 'address', 'points', 'Details'];
  .
  .
  .
  columns: any[] = [{
        name: 'id',
        title: 'Id'
      },
      {
        name: 'firstName',
        title: 'FirstName'
      },
      {
        name: 'lastName',
        title: 'LastName'
      },
      {
        name: 'email',
        title: 'Email'
      },
      {
        name: 'phoneNumber',
        title: 'PhoneNumber'
      },
      {
        name: 'address',
        title: 'Address'
      },
      {
        name: 'points',
        title: 'Points'
      },
      {
        name: 'Details',
        title: 'Details'
      },
    ]
    .
    .
    .
  drop(event: CdkDragDrop < any[] > ) {
    moveItemInArray(this.displayedColumns, event.previousIndex, event.currentIndex);
  }

}

This is just a simple test code I managed to find on internet Example on stackblitz I found The problem is, I can't manage to get the line (cdkDropListDropped)="drop($event)" to fire an event in the "drop" function in ts. I tried the functionality without table and it's working, it's firing the event (and "drop" function), but inside the table, it's not working.

I wonder if any of you had encountered a similar problem and if you managed to resolve the issue.


Solution

  • I had the same problem using Angular 9.1.12.

    I've found this example with a previous version of Angular, but using the same code it didn't work for me (stackblitz).

    So I used this workaround (making droppable the entire table) and it works:

    <table mat-table [dataSource]="tableDataSource" cdkDropList cdkDropListLockAxis="x"
        cdkDropListOrientation="horizontal" matSort
        (cdkDropListDropped)="dropListDropped($event)">
        <ng-container *ngFor="let disCol of headers; let colIndex = index" matColumnDef="{{disCol.field}}">
            <th mat-header-cell *matHeaderCellDef cdkDrag [cdkDragData]="{name: disCol.field, columIndex: colIndex}"
                mat-sort-header>
                {{disCol.field}}
            </th>
            <td mat-cell *matCellDef="let row "> {{row[disCol.field]}}
            </td>
        </ng-container>
       [...]
    </table>