Drag And Drop In Angular 7

Introduction
 
Recently, Angular has released its latest version 7.0. This major release has brought some changes in the core framework, Angular Material, toolchain etc. Let's see what's new in Angular v7.
 
What's new in Angular 7,
 
CLI prompt
 
In this new feature, when we create a new Angular app, at that time, the Angular CLI prompts us with the options which are listed below.
 
Enable Angular Routing
 
 Enable Angular Routing
Stylesheet format 
 
Stylesheet format
  • The bundle budget feature allows us to specify the bundling size with minimum and maximum values which directly put an impact on website performance.
  •  Angular Elements with the Content Projection are now supported. 
  • Virtual scroll using CDK is used to load the large numbers of the list and to build a faster user experience.
  • Drag and Drop is a completely new feature added to version 7 and the same thing we are going to discuss in this article very soon.
  • A few dependencies are updated like TypeScript 3.1, Nodejs 10 and RxJs 6.3.
So, these are some primary changes found in this new version and if you want to know more and detailed information than you can go to the official blog page from here.
 
Now, let's start with one of the new features called Drag and Drop which I was waiting for for a long time. 
 
Get Started with Drag and Drop using Angular 7
 
To work with Drag and Drop, we have the module called @angular/cdk/drag-drop which is used to provide the interface to create drag and drop functionality easily.
 
A number of options are available with Drag and Drop as listed below.
  • Basic Drag and Drop
  • Sorting with Drag and Drop
  • Drag and Drop with custom drag handle
  • Transfer items between the list 
  • Drag and Drop with different orientation
  • Locking with axis
Prerequisites
 
Nodejs > 10
We need to install the latest version of NodeJs from here.
 
    
Updated angular-cli
 
Install the latest version of angular-cli using the following npm command. 
  1. npm install -g @angular-cli@latest  
We have installed the latest version of Angular CLI and node.js. Now, let's create a new Angular 7 app. For that, follow these simple steps as described below.
  1. ng new draganddropng7  
After running the above command, CLI prompts for the question, and the first one is to create an Angular Routing module.
 
 Enable Angular Routing
 
The next question is to choose the format of Stylesheet.
 
Stylesheet format
 
So, select the appropriate options. I have allowed creating a routing module and chose the CSS format for my stylesheets. 
 
In this article, we are going to learn about the Drag and Drop options so for that we are going to create new components.
  1. ng g c basic  
  2. ng g c sorting  
  3. ng g c handle  
  4. ng g c orientation  
The next step is to configure the routing, open the file app-routing.module.ts and replace the following lines of code.
  1. import { NgModule } from '@angular/core';  
  2. import { Routes, RouterModule } from '@angular/router';  
  3. import { BasicComponent } from './basic/basic.component';  
  4. import { SortingComponent } from './sorting/sorting.component';  
  5. import { HandleComponent } from './handle/handle.component';  
  6. import { OrientationComponent } from './orientation/orientation.component';  
  7.   
  8. const routes: Routes = [  
  9.   { path: '', redirectTo: 'basic', pathMatch: 'full' },  
  10.   { path: 'basic', component: BasicComponent },  
  11.   { path: 'sorting', component: SortingComponent },  
  12.   { path: 'handle', component: HandleComponent },  
  13.   { path: 'orientation', component: OrientationComponent },  
  14. ];  
  15.   
  16. @NgModule({  
  17.   imports: [RouterModule.forRoot(routes)],  
  18.   exports: [RouterModule]  
  19. })  
  20. export class AppRoutingModule { }  
Our routing part was completed and now we are going to set up our home page with the use of different Angular Material Components, open app.module.ts file and replace with the following source code.
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3.   
  4. import { AppRoutingModule } from './app-routing.module';  
  5. import { AppComponent } from './app.component';  
  6. import { BasicComponent } from './basic/basic.component';  
  7. import { SortingComponent } from './sorting/sorting.component';  
  8. import { HandleComponent } from './handle/handle.component';  
  9. import { OrientationComponent } from './orientation/orientation.component';  
  10.   
  11. // To use material components    
  12. import { MatToolbarModule, MatMenuModule, MatInputModule, MatTableModule, MatButtonModule, MatCardModule, MatTableDataSource, MatPaginatorModule, MatSortModule } from '@angular/material';  
  13. import { BrowserAnimationsModule } from '@angular/platform-browser/animations';  
  14. import { DragDropModule } from '@angular/cdk/drag-drop';  
  15.   
  16. @NgModule({  
  17.   declarations: [  
  18.     AppComponent,  
  19.     BasicComponent,  
  20.     SortingComponent,  
  21.     HandleComponent,  
  22.     OrientationComponent  
  23.   ],  
  24.   imports: [  
  25.     BrowserModule,  
  26.     AppRoutingModule,  
  27.     BrowserAnimationsModule,  
  28.     MatToolbarModule, MatMenuModule, MatInputModule, MatTableModule, MatButtonModule, MatCardModule, MatPaginatorModule, MatSortModule,  
  29.     DragDropModule  
  30.   ],  
  31.   exports: [  
  32.     MatToolbarModule, MatMenuModule, MatInputModule, MatTableModule, MatButtonModule, MatCardModule, MatPaginatorModule, MatSortModule  
  33.   ],  
  34.   providers: [],  
  35.   bootstrap: [AppComponent]  
  36. })  
  37. export class AppModule { }  
As you can see that I have used different Material Components to design the user interface, let's jump to the home page app.component.html file and add following source code.
  1. <mat-toolbar color="accent">  
  2.   <span>Manav Pandya - C#Corner</span>  
  3.   <span class="demo-toolbar"></span>  
  4.   <button mat-button [matMenuTriggerFor]="menu">Menu</button>  
  5.   <mat-menu #menu="matMenu">  
  6.     <button [routerLink]="['/basic']" mat-menu-item>Basic Drag & Drop</button>  
  7.     <button [routerLink]="['/sorting']" mat-menu-item>Sorting</button>  
  8.     <button [routerLink]="['/handle']" mat-menu-item>Drag using Handle</button>  
  9.     <button [routerLink]="['/orientation']" mat-menu-item>Horizontal Orientation</button>  
  10.   </mat-menu>  
  11. </mat-toolbar>  
  12.   
  13. <router-outlet></router-outlet>  
Used different Angular Material Components like Menu, Card, Toolbar etc.
 
Basic Drag and Drop
 
To use Drag and Drop, we have already imported module @angular/cdk/drag-drop into the app.module.ts file, and to allow basic Drag and Drop effect we have directive named cdkDrag which allow an element to be dragged and dropped.
 
Open the file basic.component.html and paste the following source code.
  1. <mat-card>  
  2.   <div class="alert alert-info">  
  3.       <strong>Simple Drag and Drop</strong>  
  4.   </div>  
  5.   <div class="example-container mat-elevation-z8">  
  6.     <div class="example-box" cdkDrag>  
  7.       Hey, Drag Me  
  8.     </div>  
  9.   </div>  
  10. </mat-card>  
cdkDrag directive allows an element to be dragged and it is dependent on the @angular/cdk; let's see the output quickly.
Drag and Drop with Sorting
 
If we want to sort the record from the list of the items, we can do this by using directive cdkDropList, thus every item in the list will act as a separate draggable element which used cdkDrag directive. 
 
Now open the file sorting.component.html and replace the following code snippet.
  1. <mat-card>  
  2.   <div class="alert alert-info">  
  3.     <strong>Drag and Drop with Sorting</strong>  
  4.   </div>  
  5.   <div class="example-container mat-elevation-z8">  
  6.     <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">  
  7.       <div class="example-box" *ngFor="let item of items" cdkDrag>{{item}}</div>  
  8.     </div>  
  9.   </div>  
  10. </mat-card>  
To get the list of items and to implement drop event, open sorting.component.ts file and paste the following source code.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';  
  3.   
  4. @Component({  
  5.   selector: 'app-sorting',  
  6.   templateUrl: './sorting.component.html',  
  7.   styleUrls: ['./sorting.component.css']  
  8. })  
  9. export class SortingComponent  {  
  10.   
  11.   items = [  
  12.     'ITEM 1',  
  13.     'ITEM 2',  
  14.     'ITEM 3',  
  15.     'ITEM 4',  
  16.     'ITEM 5',  
  17.     'ITEM 6',  
  18.     'ITEM 7',  
  19.   ];  
  20.   
  21.   drop(event: CdkDragDrop<string[]>) {  
  22.     moveItemInArray(this.items, event.previousIndex, event.currentIndex);  
  23.   }  
  24. }   
Now we will be able to reorder the list of items without using any complex JavaScript based libraries.
 
Drag and Drop using Custom Drag Handle
 
We have seen a simple example where the whole element is to be dragged, but if you want to specify the specific place in the element from where the user can drag the element then we can do this by using directive cdkDragHandle.
 
Open the file handle.component.html and replace with the following source code.
  1. <mat-card>  
  2.   <div class="alert alert-info">  
  3.     <strong>Drag and Drop with Handle</strong>  
  4.   </div>  
  5.   <div class="example-container mat-elevation-z8">  
  6.     <div class="example-box" cdkDrag>  
  7.       Drag me using handle  
  8.       <div class="example-handle" cdkDragHandle>  
  9.         <svg width="24px" fill="currentColor" viewBox="0 0 24 24">  
  10.           <path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path>  
  11.           <path d="M0 0h24v24H0z" fill="none"></path>  
  12.         </svg>  
  13.       </div>  
  14.     </div>  
  15.   </div>  
  16. </mat-card>  
After running the above example, you can see that there is a custom drag handle is available to drag the entire element.
 
Drag and Drop using Horizontal orientation
 
By default, the orientation of the list will be vertical, but we can set it to horizontal using cdkDropListOrientation, open orientation.component.html and replace it with the following source code.
  1. <mat-card>  
  2.   <div class="alert alert-info">  
  3.     <strong>Drag and Drop with Horizontal Orientation</strong>  
  4.   </div>  
  5.   <div class="example-container mat-elevation-z8">  
  6.     <div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">  
  7.       <div class="example-box" *ngFor="let item of items" cdkDrag>{{item}}</div>  
  8.     </div>  
  9.   </div>  
  10. </mat-card>  
And to render the list of items, and to implement drop event, open orientatio.component.ts file and the code will look like this.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';  
  3.   
  4. @Component({  
  5.   selector: 'app-orientation',  
  6.   templateUrl: './orientation.component.html',  
  7.   styleUrls: ['./orientation.component.css']  
  8. })  
  9. export class OrientationComponent {  
  10.   
  11.   items = [  
  12.     'ITEM 1',  
  13.     'ITEM 2',  
  14.     'ITEM 3',  
  15.     'ITEM 4',  
  16.     'ITEM 5',  
  17.     'ITEM 6',  
  18.     'ITEM 7',  
  19.   ];  
  20.   
  21.   drop(event: CdkDragDrop<string[]>) {  
  22.     moveItemInArray(this.items, event.previousIndex, event.currentIndex);  
  23.   }  
  24.   
  25. }  
The example is the same as we have seen in the sorting demo, but with the small difference of the orientation set to horizontal.
 
Conclusion
 
Angular 7 brought a new feature and one of the features we have learned is Drag and Drop using angular/cdk, here in this article we have seen the examples of simple drag and drop, with sorting, using custom drag handle and with the different orientation.
 
I would recommend you to just refer to the complete guide from here where you will get to know more about these options. I hope this new feature will help you to implement Drag and Drop functionality in an easy manner, just download the source code attached to this article and do not forget to use CSS files, otherwise you will be unable to get the desired output.
 
Thanks for reading.