Hello Guys, This is my third article here we are learning how to drag and drop table in Angular.
Let' Start
Step 1. Create component <ng g c componentname>
Step 2. Install drage and drop from npm js  npm i angular-drag-drop.
Step 3. Add code in the your HTML file.
<mat-table [dataSource]="dataSource" class="mat-elevation-z8" cdkDropListGroup>
  <ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.columnDef">
    <mat-header-cell *matHeaderCellDef cdkDropList cdkDropListLockAxis="x" cdkDropListOrientation="horizontal"
      (cdkDropListDropped)="dropListDropped($event, i, column.columnDef)" cdkDrag
      (cdkDragStarted)="dragStarted($event, i)" [cdkDragData]="{name: column.columnDef, columIndex: i}">
      <mat-select placeholder="-- Select --" [value]="column.columnDef"
        (selectionChange)="switchColumn($event,column.columnDef)">
        <mat-option *ngIf="displayedColumns.length > 1" value="clearSelected">Clear Selection
        </mat-option>
        
        <ng-container *ngFor="let selectColumn of columns;">
          <mat-option *ngIf="!selectColumn.hidden" [value]="selectColumn.columnDef"
            [disabled]="selectColumn.selected">
            {{ selectColumn.header }}
          </mat-option>
        </ng-container>
      </mat-select>
    </mat-header-cell>
    <mat-cell *matCellDef="let row"> {{ column.cell(row) }} </mat-cell>
  </ng-container>
  <ng-container cdkColumnDef=''>
    <mat-header-cell *cdkHeaderCellDef> add </mat-header-cell>
    <mat-cell *cdkCellDef>test</mat-cell>
  </ng-container>
  <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
  <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
Here i am use material table for drage and drop column.
Step 4. Add code your typescript file.
import {
  CdkDragStart,
  CdkDropList,
  moveItemInArray
} from "@angular/cdk/drag-drop";
import { Component, OnInit, ViewChild } from "@angular/core";
import { MatPaginator, MatSort, MatTableDataSource } from "@angular/material";
import "hammerjs";
import "rxjs/add/observable/of";
import * as _ from "lodash";
export interface PeriodicElement {
  name: string;
  node_status: string;
  rssi: string;
  wattage: string;
  brightness: string;
  current: string;
}
const ELEMENT_DATA: PeriodicElement[] = [
  {
    name: "node1",
    node_status: "On",
    rssi: "High",
    wattage: "123",
    brightness: "10",
    current: "0.12"
  },
  // ... additional elements
];
@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  columns: any = [
    // ... existing columns
    {
      columnDef: "brightness",
      header: "Brightness",
      cell: element => `${element.brightness}`,
      selected: false,
      position: 0
    },
    {
      columnDef: "current",
      header: "Pole Current",
      cell: element => `${element.current}`,
      selected: false,
      position: 0
    }
  ];
  displayedColumns = this.columns
    .filter(obj => obj.selected)
    .map(obj => obj.columnDef);
  dataSource = new MatTableDataSource<PeriodicElement>(ELEMENT_DATA);
  @ViewChild(MatSort) sort: MatSort;
  previousIndex: number;
  ngOnInit() {
    for (let i = 1; i <= 100; i++) {
      const hiddenElement = {
        columnDef: i + "-hidden",
        header: "",
        cell: element => null,
        selected: false,
        hidden: true
      };
      this.columns.push(hiddenElement);
    }
    this.setDisplayedColumns();
    this.dataSource.sort = this.sort;
  }
  setDisplayedColumns() {
    // console.log(this.displayedColumns);
  }
  dragStarted(event: CdkDragStart, index: number) {
    const prevIndex = _.indexOf(this.displayedColumns, event.source.data.name);
    console.log("dragStarted", event.source.data.name, prevIndex);
    this.previousIndex = prevIndex >= 0 ? prevIndex : 0;
  }
  dropListDropped(event: CdkDropList, index: number, columnDef) {
    if (event) {
      const dropIndex = _.indexOf(this.displayedColumns, columnDef);
      if (dropIndex >= 0) {
        console.log("dropListDropped", columnDef, dropIndex);
        moveItemInArray(this.displayedColumns, this.previousIndex, dropIndex);
        this.setDisplayedColumns();
      }
    }
  }
  switchColumn(event, prevColumn, position) {
    if (event.value == "clearSelected") {
      const newEmptyColumn = _.find(this.columns, function (emptyColumn) {
        return emptyColumn.hidden === true && emptyColumn.selected == false;
      });
      event.value = newEmptyColumn.columnDef;
    }
    console.log("switchColumn", prevColumn, event.value, position);
    if (prevColumn && event.value) {
      let prevColumnIndex = _.indexOf(this.displayedColumns, prevColumn);
      if (prevColumnIndex >= 0) {
        this.displayedColumns[prevColumnIndex] = event.value;
        let newValue = _.find(this.columns, ["columnDef", event.value]);
        newValue.selected = true;
        let prevColumnValue = _.find(this.columns, ["columnDef", prevColumn]);
        prevColumnValue.selected = false;
      }
    }
  }
}
Step 5. Here I have done it on Angular's table, you can do it on any table.