How to use Angular7 (angular material) drag drop between two components
You may use properties id and cdkDropListConnectedTo to link both lists:
Component 1:
<div cdkDropList id="list-1" cdkDropListConnectedTo="list-2" (cdkDropListDropped)="drop($event)"> <div *ngFor="let item of list" cdkDrag>{{ item }}</div></div>
Component 2:
<div cdkDropList id="list-2" cdkDropListConnectedTo="list-1" (cdkDropListDropped)="drop($event)"> <div *ngFor="let item of list" cdkDrag>{{ item }}</div></div>
If you need to connect several lists to one list, you may use the following syntax: [cdkDropListConnectedTo]="['list-1', 'list-2', 'list-3', 'list-4']"
After linking the lists, you must correctly update one or both lists depending on the actions. You may do it on the drop function like this:
drop(event: CdkDragDrop<string[]>) { if (event.container.id === event.previousContainer.id) { // move inside same list moveItemInArray(this.list, event.previousIndex, event.currentIndex); } else { // move between lists }}
For moving items between lists, you will possibly want to keep track of the lists centrally. You may do so by using a Service, a Store or other methods.
Not sure if the above solution still works with angular 7.2.9 and angular material/cdk 7.3.5
It did not work for me and thus after some hard time - I managed to make it work using cdkDropListGroup directive. All cdkDropList within cdkDropListGroup will be available to drop items. You no longer need to connect Drop Lists with cdkDropListConnectedTo property
<div cdkDropListGroup><component1></component1><component2></component2></div>
You just need to create a drop method in the service and call that drop method from two components. And have to wrap these two components with cdkDropListGroup on the parent component.
App Component
<div class="wrapper"> <div cdkDropListGroup> <app-test1></app-test1> <app-test2></app-test2> </div></div>
Test1 Component
<div class="container"> <h2>Movies</h2> <div cdkDropList [cdkDropListData]="MoviesList" class="movie-list" (cdkDropListDropped)="onDrop($event)"> <div class="movie-block" *ngFor="let moviesList of MoviesList" cdkDrag>{{moviesList}}</div> </div></div> export class Test1Component implements OnInit { constructor(private ss: ShareService) { } ngOnInit() { } // Transfer Items Between Lists MoviesList = [ 'The Far Side of the World', 'Morituri', 'Napoleon Dynamite', 'Pulp Fiction', 'Blade Runner', 'Cool Hand Luke', 'Heat', 'Juice' ]; onDrop(event: CdkDragDrop<string[]>) { this.ss.drop(event); }}
Test2 Component
<div class="container"> <h2>Movies Watched</h2> <div cdkDropList [cdkDropListData]="MoviesWatched" [cdkDropListConnectedTo]="list-1" class="movie-list" (cdkDropListDropped)="onDrop($event)"> <div class="movie-block" *ngFor="let moviesWatched of MoviesWatched" cdkDrag>{{moviesWatched}}</div> </div></div>import { Component, OnInit } from '@angular/core';import { CdkDragDrop } from '@angular/cdk/drag-drop';import { ShareService } from '../share.service';@Component({ selector: 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css']})export class Test2Component implements OnInit { constructor(private ss: ShareService) { } MoviesWatched = [ 'Transformers' ]; ngOnInit() { } onDrop(event: CdkDragDrop<string[]>) { this.ss.drop(event); }}
ShareService
import { Injectable } from '@angular/core';import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';@Injectable()export class ShareService { constructor() { } public 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); } }}
Here is the working link