4
votes

I'm trying to provide scrolling while dragging a cdkDropList item. As of right now the page can't scroll without using the mousewheel to scroll. I was hoping to be able to just scroll through the page based on the dragging of the list item. After googling it looks like it wasn't possible until a few months ago?!

I found the following commit on the angular material repo: https://github.com/crisbeto/material2/commit/b4be85f6716a2d1a432ef7109aa06e7255324222

but haven't found any documentation on the angular material site. I was curious if anyone has implemented any auto drag scrolling on a CdkDropList element with Angular Material since this was released. I'm newer to angular. I've tried adding the cdkScrollable tag to the div but have been able to get the auto-scroll function to work while dragging any of the elements in the list.

Thoughts/advice?

2
You can try with event listners like when the user is drag to the near bottom of the scrollable list then scroll the list to bottom if the user drags an item on near top of the scrollable list then scroll to top.Hitech Hitesh
I guess apparently it should automatically work for the scroll. I guess theres some sort of constraint with fixed-height/width layouts/containers, I believe is what I found out.dxlachx

2 Answers

5
votes

From version 9.1.0, the auto scrolling is supported by setting cdkScrollable directive on the parent that should scroll.

So, for v9.1.0 and up, the following code should work:

<div style="height: 500px; overflow-y: auto" cdkScrollable>
  <div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let movie of movies" cdkDrag>{{movie}}</div>
  </div>
</div>

Stackblitz demo:

https://stackblitz.com/edit/angular-swaqkk-njehwg (uses Angular CDK v10.0.1)

Also, I've posted a more complete answer, which includes more examples and also solutions for Angular8, at the following topic: Angular CDK - issue with scrolling and dragging element inside nested scrollable div

1
votes

Note: cdkScrollable does not magically make anything scrollable. You have to build the subscription and action to handle the event.

Regarding cdkDropList, it will scroll if a child element contains an *ngFor with the items it is to loop over. Modified @andreivictor's answer to prove this: https://stackblitz.com/edit/angular-swaqkk-4iaqwc?file=src%2Fapp%2Fcdk-drag-drop-sorting-example.html

<div cdkDropList class="example-list" (cdkDropListDropped)="drop($event)">
    <div *ngFor="let movie of movies" >
    <ng-container *ngTemplateOutlet="Tmpl2; context:{ movieT: movie }">
    </ng-container>
</div>
<ng-template #Tmpl2 let-movieT="movieT">
    <div>
                <div class="example-box" cdkDrag>{{movieT}}</div>
    </div>
</ng-template>

Move the ngFor div into the template and rename {{movieT}} to {{movie}} and you'll see the scrolling stops. This is because the cdkDropList directive can no longer access the items inside another component. I don't know of any way to handle this scenario, but if you can avoid templates I'd imagine the scrolling should work as expected. It is also an issue if you are nesting lists. I could not get cdkDropListGroup attribute to work, though adding an id attribute and using the cdkDropListConnectedTo array attribute (found on the same link) works well.