Angular Material 16 Drag and Drop Example Tutorial

Last Updated on by in Angular
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 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

Set up Angular Project

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

Fixing TypeScript Errors

To resolve error:

Property ‘xxxName’ comes from an index signature, so it must be accessed with [‘xxxName’]

This setting makes sure profound consistency between accessing a field via the “dot” (obj.key) syntax, and “indexed” (obj["key"]) and the way which the property is declared in the type.

Without this flag, TypeScript will allow you to use the dot syntax to access fields which are not defined:

Make sure to set noPropertyAccessFromIndexSignature property to false under compilerOptions in tsconfig.json file:

"compilerOptions": {
 ...
 ...
   "strict": false,
   "noPropertyAccessFromIndexSignature": false,
 ...
 ...
}

Install Angular Material

Set up your Angular Material project by running the below command:

ng add @angular/material

Would you like to proceed? Yes
✔ Packages successfully installed.

? Choose a prebuilt theme name, or “custom” for a custom theme:
Indigo/Pink [Preview:https://material.angular.io?theme=indigo-pink]

? Set up global Angular Material typography styles? Yes
? Include the Angular animations module? Include and enable 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 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.scss 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">

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: [...]
})

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.scss 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.scss']
})

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);
  }
}

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.scss']
})

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>

The following command will start a development server that will compile your app.

ng serve --open

Your app will be served on port 4200.

Angular Material 16 Drag and Drop Example Tutorial

Digamber - Author positronX.io

Hi, I'm Digamber Singh, a New Delhi-based full-stack developer, tech author, and open-source contributor with 10+ years' experience in HTML, CSS, JavaScript, PHP, and WordPress.