Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Angular 7 cdkDropList between components?

I have a list of items (students) in a mat-list component on the left side of my screen (general list). I also have a list of class-room Components on the right side of my screen. In each class-room Component, there is a mat-list of students.

I want to be able to drag students from to the general List to one of the students lists contained inside any of the class-room Component using the new Drag&Drop API of angular material

the pseudo code looks like this:

<mat-list #studentsList="cdkDropList" cdkDropList [cdkDropListData]="students">
  <mat-list-item cdkDrag *ngFor="let student of studentes">
    {{student.name}}
  </mat-list-item>
</mat-list>

<div class="right-panel>
  <app-class-room *ngFor="let cr of classRooms" [classRoom]="cr"></app-class-room>
</div>

Obviously, I can't use the [cdkDropListConnectedTo] input on the general list as I don't have access to the student list inside the Class-room Component. How should I proceed?

like image 241
Patrick M. Avatar asked Oct 30 '18 12:10

Patrick M.


People also ask

How do you use cdkDropList?

The cdkDropList directive supports transferring dragged items between connected drop zones. You can connect one or more cdkDropList instances together by setting the cdkDropListConnectedTo property or by wrapping the elements in an element with the cdkDropListGroup attribute.

What is angular CDK used for?

The Angular Component Dev Kit (CDK) is a library of predefined behaviors included in Angular Material, a UI component library for Angular developers. It contains reusable logic for many features that are used as common building blocks for the interfaces of Angular applications.

How do you install drag and drop CDK?

Install Angular CDK Package for Drag and Drop ts file. import { DragDropModule } from '@angular/cdk/drag-drop'; @NgModule({ declarations: [...], imports: [ DragDropModule ], providers: [...], bootstrap: [...], schemas: [...] })


1 Answers

I'd like to expand on the previous answers since I couldn't find working examples for my scenarios. Please mind that I simplified this example to stress the important bits (connecting the desired lists).

The "actual transfer logic" is realized by (cdkDropListDropped)="onDrop($event)". There's a really basic example on that.

1. Connecting specific cdkDropLists in different components via cdkDropListConnectedTo

Sometimes we don't want to connect ALL child components, but only certain ones. For that we will use cdkDropListConnectedTo, BUT we will have to give every cdkDropList a unique id. The catch is that it is NOT a usual HTML id.

Wrong way

<component1 id="component1" cdkDropList> // <- NO!

We would receive an error of this kind

CdkDropList could not find connected drop list with id component1

Right way

The documentation states thatcdkDropList has a dedicated @Input() attribute for id. Hence the right way to connect the lists:

<component1 [id]="'component1'" [cdkDropListConnectedTo]="'component2'" cdkDropList></...>
<component2 [id]="'component2'" cdkDropList></...>
<component3 [id]="'component3'" cdkDropList></...>

You can now ONLY drag from component1 to component2.

Please mind that the id in this example is a string. We have to wrap the string in ' ' to pass them to @Input() (here's a little guide in case you're not familiar with it).

2. Connecting ALL cdkDropLists with cdkDropListGroup directive

Adding cdkDropListGroup to a parent element connects all child elements and allows dragging between them. cdkDropListGroup documentation.

<section cdkDropListGroup>
    <component1 cdkDropList></component1>
    <component2 cdkDropList></component2>
    <component3 cdkDropList></component3>
</section>

Every item can be transferred between component 1, 2 and 3.


Edit: Here's a working example with two components.

like image 133
s-gbz Avatar answered Sep 17 '22 16:09

s-gbz