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.