Creating Drag-n-Drop List In Angular Using Angular Material

In this article, I am going to show you how to implement Drag and Drop Lists in an Angular application.

Now, you must be wondering what Drag and Drop Lists are, right? Well, that’s natural!

Let us assume a case where you have two lists - one for the list of items you have not done yet; i.e., the pending list, and the other one for the list of items you have successfully completed, i.e., the done list. Now, it’s natural that you move an item into the list of completed things as soon as you complete it. Moreover, you always have your priorities for the things which are there on your pending list. While using these dropdown lists, you can rearrange your priorities anytime easily.

In simple words, Drag n Drop lists give you the facility to move your items from one list to another as well as rearrange items of the same list. Well, before starting the actual implementation of it, I would like to show you one demo of what we will be implementing at the end of this article.

So, let’s now start implementation. The first step is to create a new app, install Angular Material into your app, and then run it.

  • Ng new angular-dragdroplist -app
  • Cd angular- dragdroplist -app
  • ng add @angular/material
  • ng serve

Here, I am adding the screenshot of the process that the above-mentioned Material command will start.

Create Drag n Drop List In Angular Using Angular Material 

Angular Material will add the BrowserAnimationsModule to your app.module.ts. Angular Material is a library developed by the Angular Team for building high-quality UI Components in Angular that are based on Google’s Material.

Earlier, to install Angular Material on your computer, you had to go through a tedious long process. Now, it is replaced by one single command.

Create Drag n Drop List In Angular Using Angular Material 

So, let’s move to the next part. Open your newly created Angular application. Add this code into your app.module.ts file.

  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3. import { AppComponent } from './app.component';  
  4. import { BrowserAnimationsModule } from '@angular/platform-browser/animations';  
  5. import { DragDropModule } from '@angular/cdk/drag-drop';  
  6.   
  7. @NgModule({  
  8.   declarations: [  
  9.     AppComponent  
  10.   ],  
  11.   imports: [  
  12.     BrowserModule,  
  13.     BrowserAnimationsModule,  
  14.     DragDropModule  
  15.       
  16.   ],  
  17.   providers: [],  
  18.   bootstrap: [AppComponent]  
  19. })  
  20. export class AppModule { }  

Now, let's learn a little about CDK. CDK gives the developers more tools to build awesome components for the web. Also, it allows us to use features of Angular Material without adopting the Material Design Visual Language.

The next step is to add the following code to your app.component.html.

  1. <div class="container">  
  2.   <h2>To do</h2>  
  3.   
  4.   <div cdkDropList #todoList="cdkDropList" [cdkDropListData]="todo"  
  5.       [cdkDropListConnectedTo]="doneList" class="list" (cdkDropListDropped)="drop($event)">  
  6.     <div class="list-item" *ngFor="let item of todo" cdkDrag>{{item}}</div>  
  7.   </div>  
  8. </div>  
  9.   
  10. <div class="container">  
  11.   <h2>Done</h2>  
  12.   
  13.   <div cdkDropList #doneList="cdkDropList" [cdkDropListData]="done"  
  14.       [cdkDropListConnectedTo]="todoList" class="list" (cdkDropListDropped)="drop($event)">  
  15.     <div class="list-item" *ngFor="let item of done" cdkDrag>{{item}}</div>  
  16.   </div>  
  17. </div>  

 

  • Here, I am binding two lists to my HTML - one is a todo list and the other one is a done list. They both are of type cdkDropList.
  • I have assigned the names to both the forms using template reference; in my case #todoList and #doneList respectively.
  • Next, I am assigning data to both the lists using property cdkDropListData and as a value, I have assigned the names of the array which I want to give it as data.
  • Next, I am establishing the connection between my two lists using the property cdkDropListConnectedTo.
  • cdkDropListDropped is the event I am binding with my two lists. It will be fired when any of the items is dropped from the list.
  • At last, I am looping through my array and have assigned items to the lists.

 

Next, add the following code to your app.component.ts.

  1. import { Component } from '@angular/core';  
  2. import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';  
  3.   
  4. @Component({  
  5.   selector: 'app-root',  
  6. templateUrl: './app.component.html',  
  7.   styleUrls: ['./app.component.css']  
  8.   
  9. })  
  10. export class AppComponent  
  11. {  
  12.   todo = [  
  13.     'Get to work',  
  14.     'Pick up groceries',  
  15.     'Go home',  
  16.     'Fall asleep'  
  17.   ];  
  18.   
  19.   done = [  
  20.     'Get up',  
  21.     'Brush teeth',  
  22.     'Take a shower',  
  23.     'Check e-mail',  
  24.     'Walk dog'  
  25.   ];  
  26.   
  27.   drop(event: CdkDragDrop<string[]>) {  
  28.     if (event.previousContainer === event.container) {  
  29.       moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);  
  30.     } else {  
  31.       transferArrayItem(event.previousContainer.data,  
  32.           event.container.data,  
  33.           event.previousIndex,  
  34.           event.currentIndex);  
  35.     }  
  36.   }  
  37. }  

 

  • First, import three items cdkdragDrop, moveItemInArray, transferArrayItem from @angular/cdk/drag-drop.
  • Next, create two arrays - one for todo and another one for done respectively.
  • And lastly, create the function named drop which will be fired whenever one of the items will be moved (as I have explained before).
  • Now, as we know, drop function will be called in two cases -

 

  1. When we want to rearrange the items within one list only
  2. When we want to move the item from one list to other.

So, that’s the only condition I am checking inside my function.

If the previous container of the item is the same as the current one, then we want to moveItemInArray of one list and if it is not the case, then we want to transferItem from one list to the other one.

So, now it should work as per the demo I have shown you earlier.

Thank you!