Tutorial

How To Add Drag and Drop Using the Angular CDK

Published on January 10, 2019

MEAN + Serverless + GraphQL

How To Add Drag and Drop Using the Angular CDK

This tutorial is out of date and no longer maintained.

Introduction

The @angular/cdk/drag-drop package from the Angular Component Development Kit (CDK) provides you the functionality to easily create drag and drop interfaces with full flexibility. It gives you an API that makes it much easier to create complex drag and drop interfaces without having to reinvent the wheel.

In this post, we’ll briefly cover what you need to get started for drag and drop in Angular using the CDK.

Setting Up the Project

First, make sure that the package for the CDK itself is added to your project:

  1. npm install @angular/cdk

Or, using Yarn:

  1. yarn add @angular/cdk

To use the APIs for drag and drop functionality provided by Angular, import the DragDropModule like this in your app module:

app.module.ts
import { DragDropModule } from '@angular/cdk/drag-drop';

After that also add it to the list of imports:

app.module.ts
imports: [
  DragDropModule
]

Implementing the Drag and Drop Interface

Here’s the interface we’ll be creating as part of this post:

Animated gif of drag and drop interface.

Drag and Drop Interface with 4 Task Trackers

So, now that all the APIs are available we can use all the directives and modules provided by DragDropModule, and by using it we’re going to create 4 task tracks In Progress, Todo, D-Done, and QA Pass.

Note: Here I’m using the mat-card and mat-card-content components to show the tasks. In order to use this, you must also have Angular Material added to your project.

Here’s a first drag and drop example:

app.component.html
<!-- 4 Task trackers are there named "Todo", "In Progress", "D-Done", and "QA-Pass" -->

<div class="board">
  <div class="card-list mat-elevation-z1" *ngFor="let track of tracks; let i=index">

    <h2 cdkDragHandle class="mat-h2">{{track.title}}</h2>

    <div class="card-list-content" cdkDropList [id]="track.id" [cdkDropListData]="track.tasks" [cdkDropListConnectedTo]="trackIds"
      (cdkDropListDropped)="onTaskDrop($event)" [ngStyle]="{'background-color': trackColor[i]}">

      <mat-card style="margin: 2%;" *ngFor="let task of track.tasks" cdkDrag>
        <!-- Use the mat-card-content to add the proper spacing. -->
        <mat-card-content>
          <h2>{{task.title}}</h2>
          {{task.description}}
        </mat-card-content>
      </mat-card>
    </div>

  </div>
</div>

And below is the data which we are using to render the trackers and tasks:

[
  {
    "title": "Todo",
    "id": "todo",
    "tasks": [
      {
        "id": "first-task",
        "title": "First Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "In Progress",
    "id": "inprogress",
    "tasks": [
      {
        "id": "seconf-task",
        "title": "Second Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "D-Done",
    "id": "ddone",
    "tasks": [
      {
        "id": "third-task",
        "title": "Third Task",
        "description": "This is my first task"
      }
    ]
  },
  {
    "title": "QA Pass",
    "id": "qapass",
    "tasks": [
      {
        "id": "fourth-task",
        "title": "Fourth Task",
        "description": "This is my first task"
      }
    ]
  }
]
  • The cdkDropList directive is applied to a container that wraps a set of draggable items. You can add cdkDropList elements to constrain where elements may be dropped. In our example, it will be the Task Tracks.
  • The cdkDropList directive has many properties and cdkDropListData is one of them, Which is used to add data arbitrarily to the container. In our example, we are attaching Task Tracks as our data.
  • cdkDropListDropped is an event that gets emitted when the user drops an item inside the container. In our example whenever any task gets dropped inside any of the task tracks, it will call the onTaskDrop($event) method.

Here’s an example method for handling the drop event:

app.component.ts
onTaskDrop(event: CdkDragDrop<Task[]>) {
  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);
  }
}

Note the conditional statement as part of the method. In case the destination container is different from the previous container, we need to transfer the given task to the target data array. This happens if a task has been dropped on a different track.

And that’s it! You now have working drag and drop functionality.

Conclusion

Make sure you check out the official Angular Drag and Drop documentation to dig deeper into what can be done.

You can find the complete source code for this example project in this repo GitHub.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar

MEAN + Serverless + GraphQL

A tech enthusiast, expertise in MEAN + Serverless + GrapQL + Websockets

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more