Angular 11 Drag and Drop Multiple Items in a List Examples

Angular 11 drag-drop example, this tutorial will explain how to create a drag and drop feature using the Angular material library in the angular app.

By the end of this comprehensive tutorial, you will have a complete understanding of creating a draggable list in which you can reorder list items. Not just that, we will also create a draggable list whose list items can be shifted from one point to another.

Angular Material Drag-drop Example

Angular Material is an exorbitantly powerful UI library based on material design pattern. It allows you components that can help you build top-notch web application components in no time. This tutorial will use the @angular/CDK/drag-drop module to create drag-drop modules in the angular app.

The Drag-drop CDK offers you an easy method to build drag-and-drop features within UI layout, and it comes with powerful features such as:

  • Simple dragging with animations
  • Sorting within a list
  • Moving items between lists
  • Touch devices
  • Custom drag handles

Angular Drag and Drop Tutorial Overview

We will start installing a new angular project also an angular material library, focus on setting up a material library in angular app, then see how to implement angular material drag-drop CDK, which will be commenced by importing DragDropModule into the NgModule and alow us to create drag drop component using CdkDropList.

Create Angular Project

Following command commence fresh angular app installation process:

ng new angular-drag-drop-example

After complete installation, move to app root:

cd angular-drag-drop-example

Setting Up Angular Material

ng add @angular/material

On your terminal screen you will see some options:

? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink
? Set up global Angular Material typography styles? Yes
? Set up browser animations for Angular Material? Yes

This will be your updated app module file after installing material library:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

export class AppModule { }

Setting Up Angular Material CDK Drag-Drop

This step helps you learn how to install and set up angular material CDK drag-drop module in angular:

npm install @angular/cdk

Import DragDropModule from ‘@angular/cdk/drag-drop’ also register the module in imports array within the app.module.ts:

import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
  ...
  ...
  imports: [
    DragDropModule
  ],
  ...
  ...
  ...
})

Create Drag’n’Drop

Invoke this step by creating a simple Basic Drag and Drop feature, and You need to define the CDK drag attribute in HTML div, as displayed below:

Update app.component.html file:

<div class="drag-box" cdkDrag>
  Drag me around
</div>

Update app.component.scss file:

.drag-box {
  width: 220px;
  height: 220px;
  border: solid 1px #444;
  color: rgba(0, 0, 0, 0.85);
  cursor: move;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: #fff;
  border-radius: 3px;
  position: relative;
  z-index: 1;
  transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
  box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
              0 2px 2px 0 rgba(0, 0, 0, 0.14),
              0 1px 5px 0 rgba(0, 0, 0, 0.12);
}

.drag-box:active {
  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);
}

List Reorder with Drag and Drop Example

To create a simple drag and drop list, you need to first import the CdkDragDrop and moveItemInArray from ‘@angular/cdk/drag-drop’ in your angular typescript template.

Thereafter create a user names list, define a drop method, pass on an event attached to CdkDragDrop API. Call the moveItemInArray() process pass user array, previous and next index ato create the simple reorder draggable and droppable list in angular.

Update code in app.component.ts:

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 {

  usersList = [
    'Abigail',
    'Alexandra',
    'Bella',
    'Carol',
    'Donna',
    'Elizabeth',
    'Felicity',
    'Gabrielle',
    'Hannah'
  ];

  reorderList(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.usersList, event.previousIndex, event.currentIndex);
  }

}

Update code in app.component.html:

<div cdkDropList (cdkDropListDropped)="reorderList($event)" class="dragdrop-wrapper">
  <div class="dragdrop-inner" *ngFor="let user of usersList" cdkDrag> {{user}} </div>
</div>

Style list block by adding code in app.component.scss:

.dragdrop-wrapper {
    width: 450px;
    max-width: 100%;
    border: solid 1px #eee;
    min-height: 65px;
    display: block;
    background: white;
    border-radius: 3px;
    overflow: hidden;
    background-color: #ffffff;
    margin: 20px auto;
  }
  
  .dragdrop-inner {
    padding: 22px 12px;
    color: rgba(0, 0, 0, 0.87);
    border-bottom: solid 1px #eee;
    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);
  }
  
  .dragdrop-inner:last-child {
    border: none;
  }
  
  .dragdrop-wrapper.cdk-drop-list-dragging 
  .dragdrop-inner:not(.cdk-drag-placeholder) {
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  }

Drag’n’Drop Transferring List Items

Now, we are going to use cdkDropList directive to build the angular 8/9 drag and drop functionality. We can drag and drop any item within the container.

Update app.component.html file:

<div class="dragdrop-wrapper" cdkDropList #fullUserList="cdkDropList" [cdkDropListData]="usersList"
  [cdkDropListConnectedTo]="[doneList]" (cdkDropListDropped)="dropItem($event)">
  <div class="dragdrop-inner" *ngFor="let user of usersList" cdkDrag>{{user}}</div>
</div>

<div class="dragdrop-wrapper" cdkDropList #doneList="cdkDropList" [cdkDropListData]="transferred"
  [cdkDropListConnectedTo]="[fullUserList]" (cdkDropListDropped)="dropItem($event)">
  <div class="dragdrop-inner" *ngFor="let ut of transferred" cdkDrag>{{ut}}</div>
</div>

Update app.component.ts file:

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 {

  usersList = [
    'Abigail',
    'Bella',
    'Donna',
    'Elizabeth',
    'Felicity',
    'Gabrielle',
    'Hannah'
  ];

  transferred = [
    'Alexandra',
    'Carol'
  ];

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

}

Summary

Eventually, the Angular Drag & Drop example has ended. This tutorial will help you comprehend how to create drag and drop in angular using angular material drag-drop API.