Angular 7 Drag and Drop example - Angular Material CDK

https://grokonez.com/frontend/angular/angular-7/angular-7-drag-and-drop-example-angular-material-cdk

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:

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

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

Lock Direction

Set cdkDragLockAxis on cdkDrag to restrict dragging:

<div class="drag-box" cdkDragLockAxis="y" cdkDrag>
  only up/down
</div>
<div class="drag-box" cdkDragLockAxis="x" cdkDrag>
  only left/right
</div>

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).
    <div cdkDrag class="drag-box"
    (cdkDragStarted)="dragStarted($event)"
    (cdkDragEnded)="dragEnded($event)"
    (cdkDragMoved)="dragMoved($event)"
    >
    drag me
    </div>
    <p>{{state}} {{position}}</p>
    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 = &gt; 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:

<div class="drag-box-with-handler" cdkDrag>
  <div class="box-handler" cdkDragHandle>
    gkz
  </div>
</div>

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:

<div class="box-list" cdkDropList (cdkDropListDropped)="drop($event)">
  <div class="drag-box" *ngFor="let customer of customers" cdkDrag>
    {{customer.name}}
  </div>
</div>

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<string[]>) {
    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".

<div
  class="box-list-horizontal"
  cdkDropList
  cdkDropListOrientation="horizontal"
  (cdkDropListDropped)="drop($event)">
  <div class="drag-box" *ngFor="let customer of customers" cdkDrag>
    {{customer.name}}
  </div>
</div>

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:

<div cdkDropList class="box-list" (cdkDropListDropped)="drop($event)">
  <div class="drag-box" *ngFor="let customer of customers" cdkDrag>
    {{customer.name}}
    <p *cdkDragPreview>Age: {{customer.age}}</p>
  </div>
</div>

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.

<div
  class="box-list"
  cdkDropList
  #inactiveList="cdkDropList"
  id = "Inactive Customers"
  [cdkDropListData]="inactiveCustomers"
  [cdkDropListConnectedTo]="[activeList]"
  (cdkDropListDropped)="drop($event)">
  <div
    class="drag-box"
    [cdkDragData]="customer"
    *ngFor="let customer of inactiveCustomers" 
    cdkDrag>
    {{customer}}
  </div>
</div>

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<string[]>) {
    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.
    <div
    class="box-list"
    cdkDropList
    #activeList1="cdkDropList"
    id = "Active Customers 1"
    [cdkDropListData]="activeCustomers"
    [cdkDropListConnectedTo]="[inactiveList1]"
    (cdkDropListDropped)="drop($event)">
    <div class="drag-box" [cdkDragData]="customer" *ngFor="let customer of activeCustomers" cdkDrag
    (cdkDragStarted)="dragStarted($event)"
    (cdkDragEnded)="dragEnded($event)"
    (cdkDragEntered)="dragEntered($event)"
    (cdkDragExited)="dragExited($event)">
    {{customer}}
    </div>
    </div>
    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',
&gt; dropping '${event.item.data}' into '${event.container.id}');
}

dragExited(event: CdkDragExit) {
console.log('dragExited Event',
&gt; 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.
    <div
    class="box-list"
    cdkDropList
    #inactiveList2="cdkDropList"
    id = "Inactive Customers 2"
    [cdkDropListData]="inactiveCustomers"
    [cdkDropListConnectedTo]="[activeList2]"
    (cdkDropListDropped)="drop($event)"
    (cdkDropListEntered)="dropListEntered($event)"
    (cdkDropListExited)="dropListExited($event)">
    <div
    class="drag-box"
    [cdkDragData]="customer"
    *ngFor="let customer of inactiveCustomers" 
    cdkDrag>
    {{customer}}
    </div>
    </div>
    Implementations of the functions:
    import { CdkDragEnter, CdkDragExit } from '@angular/cdk/drag-drop';

...
export class TransferItemsListsComponent {

drop(event: CdkDragDrop<string[]>) {
...
console.log('dropped Event',
&gt; dropped '${event.item.data}' into '${event.container.id}');
}

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

dropListExited(event: CdkDragExit) {
console.log('dropListExited Event',
&gt; drag '${event.item.data}' from '${event.container.id}');
}
}
angular-7-drag-drop-example-transfer-lists-drop-event-handlers

Source Code

AngularMaterialCDK-Drag-Drop-example

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

Male avatar

loveprogramming

444 bài viết.
77 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
Male avatar
1 0
Tutorial Link: (Link) (Ảnh) Django is a Pythonbased free and opensource web framework that follows the modeltemplateview architectural pattern. A...
loveprogramming viết 6 tháng trước
1 0
Male avatar
1 0
https://loizenai.com/angular11nodejspostgresqlcrudexample/ Angular 11 Node.js PostgreSQL Crud Example (Ảnh) Tutorial: “Angular 11 Node.js Postg...
loveprogramming viết 5 tháng trước
1 0
Male avatar
1 0
Angular Spring Boot jwt Authentication Example Github https://loizenai.com/angularspringbootjwt/ (Ảnh) Tutorial: ” Angular Spring Boot jwt Authe...
loveprogramming viết 5 tháng trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


Male avatar
{{userFollowed ? 'Following' : 'Follow'}}
444 bài viết.
77 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!