Angular Material provides an out-of-the-box drag-and-drop feature, allowing users to reorder table columns seamlessly. This powerful user interface feature is introduced through the DragDropModule in Angular versions 7 to 16.
Angular Mat-table and column reordering
I will teach you how to change column reordering to an angular material 9 mat-table. If you would like to check features of mat-table, please see my other articles.
It can be achieve using angular cdk. This library provides several drag-and-drop features also.
As above demo of changing table columns order using drag & drop. I have added the code below how to do it using the angular7, 8 or 9+ version.
You need some module to install module @angular/material, and @angular/cdk check the package.json
{
....
"private": true,
"dependencies": {
"@angular/animations": "~9.1.0",
"@angular/cdk": "^9.2.4",
"@angular/common": "~9.1.0",
"@angular/compiler": "~9.1.0",
"@angular/core": "~9.1.0",
"@angular/forms": "~9.1.0",
"@angular/material": "^9.2.4",
...
}
Import these module in app.module.js
....
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import {MatIconModule} from '@angular/material/icon';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {CommonModule} from '@angular/common';
import { A11yModule } from '@angular/cdk/a11y';
import { CdkTableModule } from '@angular/cdk/table';
import { ScrollingModule } from '@angular/cdk/scrolling';
.......
........
const appRoutes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'home' },
{path: 'home', component: DragdropcolumnComponent},
];
@NgModule({
declarations: [AppComponent,DragdropcolumnComponent],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
RouterModule.forRoot(
appRoutes
//{ enableTracing: true } // <-- debugging purposes only
),
BrowserAnimationsModule,
MatPaginatorModule,
MatTableModule,
MatSortModule,
MatIconModule,
DragDropModule,
CommonModule,
A11yModule,
CdkTableModule,
CdkTreeModule,
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
.......
],
providers: [],
exports: [RouterModule],
bootstrap: [AppComponent],
})
export class AppModule {}
Create a component using the command, it will create .ts, .html, .css file.
ng g component dragdropcolumn
- dragdropcolumn.component.ts copy and paste the code below
import {Component, Input, OnInit} from '@angular/core';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
import {MatTableDataSource} from '@angular/material/table';
@Component({
selector: 'app-dragdropcolumn',
templateUrl: './dragdropcolumn.component.html',
styleUrls: ['./dragdropcolumn.component.css']
})
export class DragdropcolumnComponent implements OnInit {
dataSource: any;
displayedColumns = ['id', 'name', 'age', 'gender', 'country'];
rows = [
{
id: '1',
name: 'John',
age: '21',
gender: 'Male',
country: 'UK'
},
{
id: '2',
name: 'Robin',
age: '25',
gender: 'Male',
country: 'London'
},
{
id: '3',
name: 'Robert',
age: '12',
gender: 'Male',
country: 'Dubai'
},
{
id: '4',
name: 'Neeraj',
age: '23',
gender: 'Male',
country: 'India'
},
{
id: '5',
name: 'Wiliiams',
age: '30',
gender: 'Male',
country: 'Ausralia'
}
];
columns: any[] = [
{
name: 'id',
title: 'No.'
},
{
name: 'name',
title: 'Name'
},
{
name: 'age',
title: 'Age'
},
{
name: 'gender',
title: 'Gender'
},
{
name: 'country',
title: 'Country'
}
];
ngOnInit() {
this.dataSource = new MatTableDataSource(this.rows);
}
tableDrop(event: CdkDragDrop<string[]>) {
moveItemInArray(this.displayedColumns, event.previousIndex, event.currentIndex);
}
}
2. dragdropcolumn.component.html copy & paste the code below
<mat-table cdkDropList
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="tableDrop($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>
3. dragdropcolumn.component.css add below css code
.cdk-drag-preview {
box-sizing: border-box;
padding: 0 15px;
position: relative;
}
.cdk-drag-preview::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 5px;
right: 5px;
border-radius: 4px;
border: solid 1px rgba(0,0,0,0.4);
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.cdk-drag-placeholder {
color: transparent;
position: relative;
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.cdk-drag-placeholder::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 5px;
right: 5px;
border-radius: 4px;
background: rgba(0,0,0,0.1);
border: dashed 1px rgba(0,0,0,0.4);
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.mat-header-cell {
cursor: pointer;
border: dotted 3px transparent;
}
After adding these code install npm module and then start.
npm install
npm start
Open the browser and run http://localhost:4200/ . you should see the table with reorder feature.
Hello friends, this is my working example, I have added. If anything missing or you require some code. Comment in the comment section for more information of Reorder mat-table columns with angular material’s drag-and-drop.
You can find the code on git also https://github.com/infotechseo/angular-dragdrop-column
Read also How to build API using Node, Express, MongoDb and Mongoose