Angular 7 Drag and Drop - Dynamically Create Drop Zones Angular 7 Drag and Drop - Dynamically Create Drop Zones angular angular

Angular 7 Drag and Drop - Dynamically Create Drop Zones


After a full day of research, I found this pull request on Angular CDK repository on Github. Now, since I did not know how to integrate cdkDropListGroup into my example, I decited to create an array of IDs which will be added to [cdkDropListConnectedTo].

Each instance of my second list will have generated ID, and that ID will be added to array with suitable prefix (in my second list, on cdkDropList):

<div cdkDropList      [attr.id]="addId(i, j)"      [cdkDropListData]="appointment.lessons"      [cdkDropListConnectedTo]="[subjectList]"      (cdkDropListDropped)="drop($event)">

addId method:

addId(i, j) {    this.LIST_IDS.push('cdk-drop-list-' + i + '' + j);    return i + '' + j;}

(cdk-drop-list- is an ID prefix. CDK places this prefix on every element with cdkDropList attribute)

So, my array will look like:

  • cdk-drop-list-00
  • cdk-drop-list-01
  • cdk-drop-list-02
  • etc.

Now, I pass that array to [cdkDropListConnectedTo] in my first list:

<div class="subj-container"     cdkDropListOrientation="horizontal"    cdkDropList     #subjectList="cdkDropList"                [cdkDropListData]="subjects"     [cdkDropListConnectedTo]="LIST_IDS"    (cdkDropListDropped)="drop($event)">

And it works flawlessly!

Hope this will help anybody with the same problem. Also, take a look at the pull request I mentioned, my solution is only a workaround, there is probably a better solution with cdkDropListGroup


Source Link

Demo Link

For Dynamic Drag n Drop Lists, we can use ID instead of # Template variables

enter image description here

app.component.html

<div class="col-md-3" *ngFor="let week of weeks">  <div class="drag-container">    <div class="section-heading">Week {{week.id}}</div>    <div cdkDropList id="{{week.id}}" [cdkDropListData]="week.weeklist"      [cdkDropListConnectedTo]="connectedTo" class="item-list" (cdkDropListDropped)="drop($event)">      <div class="item-box" *ngFor="let weekItem of week.weeklist" cdkDrag>Week {{week.id}} {{weekItem}}</div>    </div>  </div></div>

app.component.ts

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 {  weeks = [];  connectedTo = [];  constructor() {    this.weeks = [      {        id: 'week-1',        weeklist: [          "item 1",          "item 2",          "item 3",          "item 4",          "item 5"        ]      }, {        id: 'week-2',        weeklist: [          "item 1",          "item 2",          "item 3",          "item 4",          "item 5"        ]      }, {        id: 'week-3',        weeklist: [          "item 1",          "item 2",          "item 3",          "item 4",          "item 5"        ]      }, {        id: 'week-4',        weeklist: [          "item 1",          "item 2",          "item 3",          "item 4",          "item 5"        ]      },    ];    for (let week of this.weeks) {      this.connectedTo.push(week.id);    };  }  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);    }  }}


With cdkDropListGroup you can now do:

<div cdkDropListGroup>  <div cdkDropList    [cdkDropListData]="data"    (cdkDropListDropped)="drop($event)">    <div class="row m-2">        <div *ngFor="let i of data" cdkDrag>{{i}}</div>              </div>  </div>  <div class="subj-container"     cdkDropListOrientation="horizontal"    cdkDropList     #subjectList="cdkDropList"                [cdkDropListData]="subjects"     (cdkDropListDropped)="drop($event)">   </div></div>