Angular Drag and Drop

Today I was playing with the Angular drag and drop library (@angular/cdk/drag-drop), and could not find any resource that would help me know where an item was dropped if it had not been dropped in a cdkDropList.  I saw the tutorials on material angular cdk drag-drop that showed items freely dragged, which was the functionality I was looking for.  But I wanted to save the location so next time site loaded the item would be in the same location.

However, none of the examples I could find showed how to get the drop event on the item dragged. 

Quick answer: (for those who don't want to read too much) use mouseup event. ;)

Quick Source GitHub

From all my research, it seems that if you have the items in a cdkDropList and drag them to a cdkDropList (or cdkDropListConnectedTo), then you can get the drop event.  However, it then positions all items in the list next to each other or on top of each other depending on cdkDropListOrientation.

In this blog I will show you how to do both, dropping in a list and dropping anywhere.  I am assuming you know how to use angular and just want some insight on cdkDragDrop library. 

First create a new angular project, I am going to make one with two pages.  The first page will have the drag and drop components.  The second page will just be there so we can leave and come back to the first page and see our items didn't move around.

After the project is created use npm or yarn or whatever to install @angular/cdk. I use npm so "npm install @angular/cdk"

Then I created two components so that the app could switch between them.  So a high level of the project structure is:

page-one
  page-one.component.*
page-two
  page-two.component.*
app-routing.module.ts
app.component.*
app.module.ts

Key things to know:

app.module.ts needs

import { DragDropModule } from '@angular/cdk/drag-drop';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

AND

  imports: [
    BrowserModule,
    AppRoutingModule,
    DragDropModule,
    BrowserAnimationsModule
  ],

In page-one.component.ts a structure is declared with 4 elements that will make the list of items that can be dragged.  These will always end up back in the list in whatever order they are dragged to.

  public divList:any[] = [{title:"One", color:"#00ffff"},
                          {title:"Two", color: "#7fffd4"}, 
                          {title:"Three", color: "#ffe4c4"}, 
                          {title:"Four", color: "#d2691e"}];

page-one.component.html will contain the items that can be dragged in a list and one item that can be dragged anywhere on the page.  Items in the list when dropped will call an event cdkDropListDropped.   In order to capture the dropping of the "free drag" item it will use a mouseup event.

<!-- Create the list of times that can be dragged in the list only -->
<!-- Dragging items in this list can cause them to change order -->
<div
  class="shuffle"
  cdkDropList
  [cdkDropListData]="divList"
  (cdkDropListDropped)="onDivDrop($event)"
  cdkDropListOrientation="horizontal"
>
  <div
    *ngFor="let myDiv of divList"
    style="width: 100px; height: 100px"
    [style.background-color]="myDiv.color"
    cdkDrag
    (cdkDropListDropped)="onDivDrop($event)"
  >
    {{ myDiv.title }}
  </div>
</div>

<!-- This item can be dragged any where on the web page. -->
<div
  class="freedom"
  cdkDrag
  (mouseup)="saveMe($event)"
  [style.top]="getTop()"
  [style.left]="getLeft()"
>
  I can go anywhere...
</div>

The code for the events looks like:

  onDivDrop(event: CdkDragDrop<any>){
    if (event.previousContainer === event.container){
      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
    }
  }

  saveMe(event:any){
    let xPos:number = event.pageX;
    let yPos:number = event.pageY;
    this.dataService.setData(xPos, yPos);
  }

That's the key to the whole free-form drag and drop items is the mouseup event.   This event will give you a bunch of information about the item being dropped and most importantly to my project; where it is dropped.

Full code is here on GITHUB.  The project stores the location values in a data service so you can switch between pages and the item will be where you left it.

 

 

Add comment