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>
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>
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>
Note: You can also read in details about other drag and drop features from material.angular.io