Drag and Drop.

The Drag and Drop interface gets the support from CDK and includes the features like automatically rendering as the user moves items and also includes the helper methods for the record or transfer of items in the lists like moveItemInArray and transferArrayItem.

Drag and Drop using Angular 7.

To use Drag and Drop, we have the module called @angular/cdk/drag-drop which is used to provide the interface to create drag and drop functionality easily with support for free dragging, Styling, sorting within a list, transferring items between lists, animations, touch devices, custom drag handles, previews, and placeholders, in addition to horizontal lists and locking along an axis, Attaching data.

Many options are available with Drag and Drop as listed below.

  • Basic Drag and Drop
  • Reordering lists
  • Transferring items between lists
  • Drag and Drop with different orientation
  • Locking with axis
  • Attaching data
  • Animations
  • Customizing the drag placeholder

Basic Drag and Drop

Import DragDropModule into the NgModule where you want to use drag-and-drop features. To make the elements draggable you can now add the cdkDrag directive.

When draggable elements present outside of the cdkDropList element it can be freely moved around the page. You can add cdkDropList elements to restrict where elements to be dropped.

Example

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    DragDropModule,
    BrowserAnimationsModule
  ],
  exports: [
    BrowserAnimationsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
import {Component} from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
}
.example-box {
  width: 200px;
  height: 200px;
  border: solid 1px #ccc;
  color: rgba(0, 0, 0, 0.87);
  cursor: move;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  background: #fff;
  border-radius: 4px;
  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);
}

.example-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);
}
<div
    class="example-box"
    cdkDrag
>
    Drag me around
</div>
SahosoftTutorials-DragAndDropBasic

Reordering lists.

To add cdkDropList around a set of cdkDrag elements groups the draggable into a reorderable collection. Items will automatically be rearranged as an element moves. Always Keep in mind that this will not update your data model you have to use the cdkDropListDropped event to update the data model once the user finishes dragging.

Example

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    DragDropModule,
    BrowserAnimationsModule
  ],
  exports: [      
    BrowserAnimationsModule  
  ],      
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
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 = [
    '1. How to upgrade to Angular 7',
    '2. Angular 7 CLI Prompts',
    '3. Application Performance',
    '4. Documentation Updates',
    '5. Dependency Updates',
    '6. Drag and Drop',
    '7. Virtual Scrolling',
    '8. Improved Accessibility of Selects',
    '9. Partner Launches',
    '10. Angular Elements'
  ];

  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.movies, event.previousIndex, event.currentIndex);
  }
}
}
.example-list {
    width: 500px;
    max-width: 100%;
    border: solid 1px #ccc;
    min-height: 60px;
    display: block;
    background: white;
    border-radius: 4px;
    overflow: hidden;
    margin-left: 300px;
    margin-top: 50px;
}

.example-box {
  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);
}

.example-box:last-child {
  border: none;
}

.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
<div
    cdkDropList
    class="example-list"
    (cdkDropListDropped)="drop($event)"
>
    <div
        class="example-box"
        *ngFor="let movie of movies"
        cdkDrag
    >
        {{movie}}
    </div>
</div>
SahosoftTutorials-Reordering lists

Transferring items between lists.

The cdkDropList directive supports the transfer of dragged items between connected drop zones. By setting the cdkDropListConnectedTo property you can connect one or more cdkDropList instances together or by wrapping the elements in an element with the cdkDropListGroup attribute.

Example

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    DragDropModule,
    BrowserAnimationsModule
  ],
  exports: [      
    BrowserAnimationsModule  
  ],      
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
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 {
  todo = [
    'Angular 5',
    'Angular js',
    'CSS',
    'Javascript',
    'Mango DB'
  ];

  done = [
    'Angular 7',
    'TypeScript',
    'HTML 5',
    'Entity Freamwork',
    'Bootstrap',
    'Sql Server'
  ];

  drop(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);
    }
  }
}
.example-container {
  width: 400px;
  max-width: 100%;
  margin: 0 2px 2px 100px;
  display: inline-block;
  vertical-align: top;
}

.example-list {
  border: solid 1px #ccc;
  min-height: 60px;
  background: white;
  border-radius: 4px;
  overflow: hidden;
  display: block;
}

.example-box {
  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);
}

.example-box:last-child {
  border: none;
}

.example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) {
  transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
<div class="example-container">
    <h>>To do</h2>

    <div
        cdkDropList
        #todoList="cdkDropList"
        [cdkDropListData]="todo"
        [cdkDropListConnectedTo]="[doneList]"
        class="example-list"
        (cdkDropListDropped)="drop($event)"
    >
        <div
            class="example-box"
            *ngFor="let item of todo"
            cdkDrag
        >
            {{item}}
        </div>
    </div>
</div>

<div class="example-container">
    <h2>Done </h2>

    <div
        cdkDropList
        #doneList="cdkDropList"
        [cdkDropListData]="done"
        [cdkDropListConnectedTo]="[todoList]"
        class="example-list"
        (cdkDropListDropped)="drop($event)"
    >
        <div
            class="example-box"
            *ngFor="let item of done"
            cdkDrag
        >
            {{item}}
        </div>
    </div>
</div>

<div
    cdkDropList
    class="example-list"
    (cdkDropListDropped)="drop($event)"
>
    <div
        class="example-box"
        *ngFor="let movie of movies"
        cdkDrag
    >
        {{movie}}
    </div>
</div>
SahosoftTutorials-Transferring items between lists

Note: You can also read in details about other drag and drop features from material.angular.io