Angular 7 Drag and Drop example – Angular Material CDK

angular-7-drag-drop-example-meterial-cdk-feature-image

The @angular/cdk/drag-drop module helps us drag single item or sort it within a horizontal/vertical list, transfer items between lists, show animations, previews, placeholders, custom drag handles. In this tutorial, we’re gonna create many simple examples that show you how to work with Angular 7 Material CDK – Drag and Drop.

Related Post: Angular 7 Virtual Scroll example – Angular Material CDK

Setup Angular 7 Material CDK

– Run cmd:
npm install @angular/material @angular/cdk

– Import DragDropModule into NgModule:

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

@NgModule({
  declarations: [...],
  imports: [
    ...
    DragDropModule
  ],
  ...
})
export class AppModule { }

Angular 7 Drag and Drop item

Basic

Add the cdkDrag directive to element to make them draggable:

drag me

angular-7-drag-drop-example-basic-dragable

Lock Direction

Set cdkDragLockAxis on cdkDrag to restrict dragging:

only up/down
only left/right

angular-7-drag-drop-example-lock-direction

Event Handler

Add functions on cdkDrag to handle events:
cdkDragStarted: emits when user stops dragging.
cdkDragEnded: emits when user starts dragging.
cdkDragMoved: emits when user is dragging the item (for every pixel).

drag me

{{state}} {{position}}

implement the functions:

import { CdkDragEnd, CdkDragStart, CdkDragMove } from '@angular/cdk/drag-drop';
...
export class DragComponent implements OnInit {
  state = '';
  position = '';
  ...

  dragStarted(event: CdkDragStart) {
    this.state = 'dragStarted';
  }

  dragEnded(event: CdkDragEnd) {
    this.state = 'dragEnded';
  }

  dragMoved(event: CdkDragMove) {
    this.position = `> Position X: ${event.pointerPosition.x} - Y: ${event.pointerPosition.y}`;
  }
}

angular-7-drag-drop-example-event-handler

With a Handle

If we want to restrict the draggable area by a handle element, just add cdkDragHandle directive to an element inside of cdkDrag:

gkz

angular-7-drag-drop-example-with-handle

Angular 7 Drag & Drop items in a List

Basic Sorting List

Cover a set of cdkDrag elements by cdkDropList will automatically rearrange the list when an element moves. To update that list, we listen cdkDropListDropped event:

{{customer.name}}

We use drag-and-drop CDK moveItemInArray function to move an item and to calculate the new index of the dropped item inside the array:

import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
...
export class SortListComponent implements OnInit {
  customers = [
    { name: 'Adam', age: 23 },
    { name: 'Jack', age: 27 },
    { name: 'Katherin', age: 26 },
    { name: 'John', age: 30 },
    { name: 'Watson', age: 42 },
  ];

  drop(event: CdkDragDrop) {
    moveItemInArray(this.customers, event.previousIndex, event.currentIndex);
  }
}

angular-7-drag-drop-example-basic-sort-list

Horizontal List

By default, cdkDropList directive make the list vertical. We can change by setting the orientation property to "horizontal".

{{customer.name}}

angular-7-drag-drop-example-horizontal-list

Animations

To set up your animations, we define a transition that targets transform property.
drag-and-drop CDK supports animations while:
– sorting an element inside a list => .cdk-drag

.cdk-drag {
    transition: transform 300ms ease;
}

angular-7-drag-drop-example-animation-sort-list

– animating it from the position we dropped it to final place in the list => .cdk-drag-animating

.cdk-drag-animating {
    transition: transform 300ms ease;
}

angular-7-drag-drop-example-animation-sort-list-simple

Placeholder
Default placeholder

Use .cdk-drag-placeholder to show a placeholder element instead of the real element as it’s being dragged inside a cdkDropList. By default, this will look exactly like the element that is being sorted.

.cdk-drag-placeholder {
    background: #ccc;
    border: dotted 1px #999;
    transition: transform 500ms ease;
}

angular-7-drag-drop-example-placeholder

Custom placeholder

Using *cdkDragPlaceholder directive, we can replace default placeholder with a custom one:

.box-custom-placeholder {
    height: 20px;
    width: 120px;
    background: #fff;
    border: dotted 1px #0084ff;
    transition: transform 200ms ease;
}

.box-list.cdk-drop-list-dragging .drag-box:not(.cdk-drag-placeholder) {
    transition: transform 500ms ease;
}

angular-7-drag-drop-example-custom-placeholder

With Preview

When a cdkDrag element is picked up and dragged, a preview element could be visible. By default, the element looks exactly like the element that is being dragged.
We use .cdk-drag-preview to define preview CSS:

.cdk-drag-preview {
    box-shadow: 0 3px 3px -3px #0084ff;
}

We also need to provide a custom template using *cdkDragPreview:

{{customer.name}}

Age: {{customer.age}}

angular-7-drag-drop-example-drag-preview

Angular 7 Drag & Drop between Lists

Basic

We can connect one or more cdkDropList together using cdkDropListConnectedTo property. Then we set cdkDropListData and cdkDragData for associating data with cdkDropList and cdkDrag.

{{customer}}

Implementation of cdkDropListDropped function will use drag-and-drop CDK moveItemInArray and transferArrayItem:

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

...
export class TransferItemsListsComponent {
  inactiveCustomers = [
    'Adam',
    'Jack',
    'Katherin'
  ];

  activeCustomers = [
    'John',
    'Watson'
  ];

  drop(event: CdkDragDrop) {
    if (event.previousContainer === event.container) {
      console.log('dropped Event',
        `> dropped '${event.item.data}' into '${event.container.id}'`);
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    } else {
      console.log('dropped Event',
        `> dropped '${event.item.data}' into '${event.container.id}'`);
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex);
    }
  }
}

angular-7-drag-drop-example-transfer-lists-item

Event Handler with List
Drag Event Handlers

cdkDragStarted: emits when the user starts dragging the item.
cdkDragEnded: emits when the user stops dragging the item.
cdkDragEntered: emits when the item are moved into a new container.
cdkDragExited: emits when dragging the item into another container.

{{customer}}

Implementations of the functions:

import {
  moveItemInArray, transferArrayItem,
  CdkDragDrop, CdkDragStart, CdkDragEnd, CdkDragEnter, CdkDragExit
} from '@angular/cdk/drag-drop';
...
export class TransferItemsListsComponent {
  ...

  dragStarted(event: CdkDragStart) {
    console.log('dragStarted Event > item', event.source.data);
  }

  dragEnded(event: CdkDragEnd) {
    console.log('dragEnded Event > item', event.source.data);
  }

  dragEntered(event: CdkDragEnter) {
    console.log('dragEntered Event',
      `> dropping '${event.item.data}' into '${event.container.id}'`);
  }

  dragExited(event: CdkDragExit) {
    console.log('dragExited Event',
      `> drag '${event.item.data}' from '${event.container.id}'`);
  }
}

angular-7-drag-drop-example-transfer-lists-drag-event-handlers

Drop Event Handlers

cdkDropListDropped: emits when an item was dropped inside the container.
cdkDropListEntered: emits when a new item is dragged into this container.
cdkDropListExited: emits when an item is dragged from this container into another container.

{{customer}}

Implementations of the functions:

import { CdkDragEnter, CdkDragExit } from '@angular/cdk/drag-drop';

...
export class TransferItemsListsComponent {

  drop(event: CdkDragDrop) {
    ...
      console.log('dropped Event',
        `> dropped '${event.item.data}' into '${event.container.id}'`);
  }

  dropListEntered(event: CdkDragEnter) {
    console.log('dropListEntered Event',
      `> dropping '${event.item.data}' into '${event.container.id}'`);
  }

  dropListExited(event: CdkDragExit) {
    console.log('dropListExited Event',
      `> drag '${event.item.data}' from '${event.container.id}'`);
  }
}

angular-7-drag-drop-example-transfer-lists-drop-event-handlers

Source Code

AngularMaterialCDK-Drag-Drop-example

6 thoughts on “Angular 7 Drag and Drop example – Angular Material CDK”

  1. Hi @all,
    Is der any way to make a vertical and horizontal list?
    Like that:
    1 2 3 4 5 6
    7 8 9 a b c
    d e f g
    Where i can drag “e” to positon after 4?

    Greetings

  2. i have a scenario that i need to design a card like identity card organization customize the card using drag and drop means putting the name , expiry etc on card which is basically a image how can i utilize it so that it will be used in other page means i set from organization page and resemble the result in the other page after saving the style of it

  3. How can i lock element in position?
    Example:
    I have [a,b,c,d,e] array.
    I want that ‘a’ and ‘b’ to be locked and ‘c’, ‘d’ and ‘e’ can never be before ‘b’ neither ‘a’.

    Thanks

  4. Thanks for the great work man , really appreciate . Looking for the exact code.

    Once again thank you mate. Lot’s of love.

Leave a Reply

Your email address will not be published. Required fields are marked *