Angular7 - Materials/CDK-Drag and Drop



The new Drag and Drop feature added to Angular 7 CDK helps to drag and drop the elements from the list. We will understand the working of Drag and Drop Module with the help of an example. The feature is added to cdk. We need to first download the dependency as shown below −

npm install @angular/cdk --save
Drag and Drop Feature

Once the above step is done. Let us import the drag and drop module in app.module.ts as shown below −

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule , RoutingComponent} from './app-routing.module';
import { AppComponent } from './app.component';
import { NewCmpComponent } from './new-cmp/new-cmp.component';
import { ChangeTextDirective } from './change-text.directive';
import { SqrtPipe } from './app.sqrt';
import { MyserviceService } from './myservice.service';
import { HttpClientModule } from '@angular/common/http';
import { ScrollDispatchModule } from '@angular/cdk/scrolling';
import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
   declarations: [
      SqrtPipe,
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective,
      RoutingComponent
   ],
   imports: [
      BrowserModule,
      AppRoutingModule,
      HttpClientModule,
      ScrollDispatchModule,
      DragDropModule
   ],
   providers: [MyserviceService],
   bootstrap: [AppComponent]
})
export class AppModule { }

The DragDropModule is imported from '@angular/cdk/drag-drop' and the module is added to import array as shown above.

We will use details from the api, (http://jsonplaceholder.typicode.com/users) to be displayed on the screen. We have service which will fetch the data from the api as shown below −

myservice.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
   providedIn: 'root'
})
export class MyserviceService {
   private finaldata = [];
   private apiurl = "http://jsonplaceholder.typicode.com/users";
   constructor(private http: HttpClient) { }
   getData() {
      return this.http.get(this.apiurl);
   }
}

Once done call the service inside app.component.ts as shown below −

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 7 Project!';
   public personaldetails = [];
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.myservice.getData().subscribe((data) => {
         this.personaldetails = Array.from(Object.keys(data), k=>data[k]);
         console.log(this.personaldetails);
      });
   }
}

We have the required data available in personaldetails variable. Now let us use the same to display to the user as shown below −

<h3>Angular 7 - Drag and Drop Module</h3>
<div>
   <div *ngFor="let item of personaldetails; let i = index" class="divlayout”>
      {{item.name}}
   </div >
</div>

We have added class = ”divlayout” and the details of the class are in app.component.css.

.divlayout{
   width: 40%;
   background-color: #ccc;
   margin-bottom: 5px;
   padding: 10px 10px;
   border: 3px solid #73AD21;
}

Following screen will be displayed in the browser −

Drag Drop

It will not drag and drop anything, we need to add the dragdrop cdk properties in app.component.html as shown below −

<h3>Angular 7 - Drag and Drop Module</h3>
<div cdkDropList
   #personList = "cdkDropList"
   [cdkDropListData] = "personaldetails"
   [cdkDropListConnectedTo] = "[userlist]"
   class = "example-list"
   (cdkDropListDropped) = "onDrop($event)" >
   
   <div *ngFor = "let item of personaldetails; 
      let i = index" class = "divlayout" cdkDrag>
      {{item.name}}
   </div >
</div&t;

The highlighted ones are all the properties required to perform drag and drop. When you check in the browser, it allows you to drag the item. It will not drop it in the list and will remain as it is when you leave the mouse pointer.

Drag Drop Module

Here it allows to drag the item from the list but once you leave the mouse pointer it will go and settle in the same place. To add the drop feature, we need to add the event onDrop in app.component.ts as shown below −

First we have to import the dragdrap cdk modules as shown below −

import {CdkDragDrop, moveItemInArray, transferArrayItem} 
from '@angular/cdk/drag-drop';

Here is the full code in app.component.ts −

import { Component } from '@angular/core';
import { MyserviceService } from './myservice.service';
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent {
   title = 'Angular 7 Project!';
   public personaldetails = [];
   constructor(private myservice: MyserviceService) {}
   ngOnInit() {
      this.myservice.getData().subscribe((data) => {
         this.personaldetails = Array.from(Object.keys(data), 
         k=>data[k]);
         console.log(this.personaldetails);
      });
   }
   onDrop(event: CdkDragDrop<string[]>) {
      if (event.previousContainer === event.container) {
         moveItemInArray(event.container.data, 
            event.previousIndex, event.currentIndex);
      } else {
         transferArrayItem(event.previousContainer.data,
         event.container.data,
         event.previousIndex,
         event.currentIndex);
      }
   }
}

The function onDrop takes care of dropping the item dragged in the position required.

It makes use of the moveItemInArray and transferArrayItem we have imported from cdk dragdrop module.

Now let us see the demo again in the browser −

Drag Drop Position

Now it allows you to drag and drop the item in the position required as shown above. The feature works very smoothly without any flicker issues and can be used in your application wherever the need arises.

Advertisements