Angular 16 Drag and Drop Tutorial with Material Library

Last updated on: by Digamber
Develop Angular Drag and Drop functionality with Angular material library. I will create a basic app in which a user can drag and drop items in a movies list.

As we know, Angular Material offers lots of useful UI components to build an app from scratch. I will take help of the Angular Material 13 theme to develop drag and drop.

Angular Material Drag and Drop Example

  • Set up Angular Project
  • Set up Angular CDK Drag and Drop API
  • Create Drag and Drop Reordering Lists
  • Transfer Items Between Lists using cdkDropList
  • Angular Drag and Drop Code Files
  • Demo Angular Material Drag and Drop

1. Set up Angular project and Angular Material Library

ng new angular-drag-drop

Angular CLI will ask you the following questions…

Would you like to add Angular routing?
Select y and Hit Enter.

Which stylesheet format would you like to use? (Use arrow keys)
Choose CSS and hit Enter

cd angular-drag-drop

In order to remove strict type warnings or errors make sure to set “strict”: false and "strictTemplates": false under compilerOptions and angularCompilerOptions properties in tsconfig.json file.

Install Angular Material and Angular Animations

npm install --save @angular/material @angular/cdk @angular/animations

Let us see how to import Angular Material in Angular Drag and Drop App.

app.module.ts

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
  declarations: [...],
  imports: [
    BrowserAnimationsModule
  ],
  providers: [...],
  bootstrap: [...],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

Importing Angular Material 13 theme

Angular material comes with deeppurple-amber, purple-green, pink-bluegrey and indigo-pink theme. In order to apply material theme in angular drag and drop app, we must include a theme in your global styles.css file.

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

You may also use material design icons in your project, all you have to do just include the below code in your index.html file.

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

2. Set up Angular CDK Drag and Drop API

The angular/cdk/drag-drop module provides access for creating a drag and drop interface with full flexibility.

The Angular Component Development Kit (CDK) support free dragging, sorting the list, transferring items from the lists, animations, drag handles, place holders, previews and locking along an axis. Now, this is more comfortable and easy with API offered along with the kit.

Install Angular CDK Package for Drag and Drop

npm install @angular/cdk

To work with Angular Drag and Drop, we must import the DragDropModule service within the app.module.ts file.

import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
  declarations: [...],
  imports: [
    DragDropModule
  ],
  providers: [...],
  bootstrap: [...],
  schemas: [...]
})

3. Create Reordering Lists Functionality with Angular Drag and Drop

  • The set of items that can be dragged are wrapped in the container where the cdkDropList directive is applied. By adding the cdkDropList, you have certain restrictions in dropping the elements.
  • When the user drops an item in the container, you can see the derivate appearing cdkDropListDropped. For instance, the Movie name from the example will call for the function of drop($event). This event is being called whenever the user drags and drops movie’s name from the movie’s list.

Go to app.component.ts file and paste the below code.

<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let movieName of Movies" cdkDrag>{{movieName}}</div>
</div>

To make our list look good, we must include the CSS classes within the app.component.css file.

.wrapper {
  margin: 25px auto;
  max-width: 600px;
  text-align: center;
  padding: 0 20px;
}
.container {
  width: 45%;
  margin: 0 25px 25px 0;
  display: inline-block;
  vertical-align: top;
}
.movie-list {
  width: 80%;
  border: solid 1px #ccc;
  min-height: 60px;
  display: inline-block;
  background: white;
  border-radius: 4px;
  overflow: hidden;
  margin-top: 25px;
}
.movie-block {
  padding: 20px 10px;
  border-bottom: solid 1px #ccc;
  color: rgba(0, 0, 0, 0.87);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  cursor: move;
  background: white;
  font-size: 14px;
}
.cdk-drag-preview {
  box-sizing: border-box;
  border-radius: 4px;
  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 {
  opacity: 0;
}
.cdk-drag-animating {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.movie-block:last-child {
  border: none;
}
.movie-list.cdk-drop-list-dragging .movie-block:not(.cdk-drag-placeholder) {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

I will be calling drop() method for dragging and dropping HTML element in Angular app. moveItemInArray function is used within the drop() method and, it takes three arguments.

import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  Movies = [
    'Blade Runner',
    'Cool Hand Luke',
    'Heat',
    'Juice',
    'The Far Side of the World',
    'Morituri',
    'Napoleon Dynamite',
    'Pulp Fiction'
  ];
  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.Movies, event.previousIndex, event.currentIndex);
  }
}

4. Transfer Items Between Lists using cdkDropList

With the help of cdkDropList directive, we can drag the item from one drop zone to another dropzone. As you can see we have two blocks, movies list and watched movies list. With the help of Angular drag and drop, we can interchange movies data between both the lists.

As you can see I used 2 arrays one is filled with movies name, and the other one is empty.

Then go to app.component.ts file and include the following code.

import { Component } from '@angular/core';
import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  // Transfer Items Between Lists
  MoviesList = [
    'The Far Side of the World',
    'Morituri',
    'Napoleon Dynamite',
    'Pulp Fiction',
    'Blade Runner',
    'Cool Hand Luke',
    'Heat',
    'Juice'
  ];
  MoviesWatched = [
  ];
  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);
    }
  }  
}

Go to app.component.html file and paste the below code.

<div class="container">
   <h2>Movies</h2>
   <div 
   cdkDropList 
   #moviesList="cdkDropList" 
   [cdkDropListData]="MoviesList"
   [cdkDropListConnectedTo]="[doneMovieList]" 
   class="movie-list" 
   (cdkDropListDropped)="onDrop($event)">
   <div class="movie-block" *ngFor="let moviesList of MoviesList" cdkDrag>{{moviesList}}</div>
</div>
</div>
<div class="container">
   <h2>Movies Watched</h2>
   <div 
   cdkDropList 
   #doneMovieList="cdkDropList" 
   [cdkDropListData]="MoviesWatched"
   [cdkDropListConnectedTo]="[moviesList]" 
   class="movie-list" 
   (cdkDropListDropped)="onDrop($event)">
   <div class="movie-block" *ngFor="let moviesWatched of MoviesWatched" cdkDrag>{{moviesWatched}}</div>
</div>
</div>

5. Angular Drag and Drop Code Files

GitHub Resources

6. Angular Drag and Drop Examples

Digamber

A Full-stack developer with a passion to solve real world problems through functional programming.