question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BUG: CdkDropList drop position after scroll is wrong

See original GitHub issue

Reopening #13823 as it was closed as duplicate of #13588 but it is not.

#13588 is about implementing automatic scrolling after drag overshoot

I have already implemented a automatic scrolling (it is a very specific solution for our use case). When item is dropped after automatic scroll , drop receiver is miscalculated.

Bug

CdkDropList: Drop position is wrong after scrolling

What is the expected behavior?

Drop target should match element under mouse pointer after scroll

What is the current behavior?

Scrolling is not taken into consideration while calculating drop element

What are the steps to reproduce?

https://stackblitz.com/edit/cdk-drop-list-scroll

Steps:

1.Start dragging top most element 2. Drag past container towards down 3. Wait till everything is scrolled down 4. now drag element back into container 5. Drop the element

More info

https://github.com/angular/material2/blob/26c73e04350fa9a159a8e0319b9d4837df04ea5b/src/cdk/drag-drop/drop-list.ts#L388

_cachePositions need to be called again whenever drag is active and scroll container is scrolled.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Angular CLI: 7.0.3 Node: 10.12.0 OS: win32 x64 Angular: 7.0.1 … animations, cdk, common, compiler, compiler-cli, core, forms … http, language-service, material, platform-browser … platform-browser-dynamic, router

Package Version

@angular-devkit/architect 0.10.3 @angular-devkit/build-angular 0.10.3 @angular-devkit/build-optimizer 0.10.3 @angular-devkit/build-webpack 0.10.3 @angular-devkit/core 7.0.3 @angular-devkit/schematics 7.0.3 @angular/cli 7.0.3 @ngtools/webpack 7.0.3 @schematics/angular 7.0.3 @schematics/update 0.10.3 rxjs 6.3.3 typescript 3.1.3 webpack 4.19.1

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:6
  • Comments:30 (1 by maintainers)

github_iconTop GitHub Comments

5reactions
Musuelcommented, Mar 30, 2019

Hello,

I developped a directive allowing a drop list to automatically scroll horizontally/vertically and refresh drop positions. Simply put the dropListScroller directive on the CdkDropList. Note that I had to use a private property of DropListRef: _itemPositions.

Here is the stackblitz: drop-list-scroller

Let me know if it fit your needs.

@crisbeto Do you think it would be possible to make _itemPositions public in DropListRef ? What do you think about this kind of directive ?

It may be related to #13588.

3reactions
techy2493commented, Jan 2, 2019

@abdulkareemnalband Here is a diff of the changes I had to make the the CDK library to get a working work-around. It is not ideal, and it is given without warranty or guarantee that it will work in any situation other than my own. However it should give you a place to start to find your own solution.

By viewing this diff you agree that this code is not supported by me or the Angular Material team it is given only as an example with no guarantee... Click here to view diff.

diff --git a/src/cdk/drag-drop/drop-list-ref.ts b/src/cdk/drag-drop/drop-list-ref.ts
index a99e89c9..ff81d21f 100644
--- a/src/cdk/drag-drop/drop-list-ref.ts
+++ b/src/cdk/drag-drop/drop-list-ref.ts
@@ -160,6 +160,9 @@ export class DropListRef<T = any> {
 
   /** Amount of connected siblings that currently have a dragged item. */
   private _activeSiblings = 0;
+  /** Scroll Offset */
+  private _scrollXOffset = 0;
+  private _scrollYOffset = 0;
 
   constructor(
     public element: ElementRef<HTMLElement>,
@@ -192,6 +195,8 @@ export class DropListRef<T = any> {
     this._activeDraggables = this._draggables.slice();
     this._cachePositions();
     this._positionCache.siblings.forEach(sibling => sibling.drop._toggleIsReceiving(true));
+    this._scrollXOffset = this.element.nativeElement.scrollLeft;
+    this._scrollYOffset = this.element.nativeElement.scrollTop;
   }
 
   /**
@@ -334,8 +339,11 @@ export class DropListRef<T = any> {
       return;
     }
 
+    const newItemX = pointerX + (this.element.nativeElement.scrollLeft - this._scrollXOffset)
+    const newItemY = pointerY + (this.element.nativeElement.scrollTop - this._scrollYOffset)
+
     const siblings = this._positionCache.items;
-    const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);
+    const newIndex = this._getItemIndexFromPointerPosition(item, newItemX, newItemY, pointerDelta);
 
     if (newIndex === -1 && siblings.length > 0) {
       return;
@@ -463,6 +471,8 @@ export class DropListRef<T = any> {
     this._positionCache.siblings = [];
     this._previousSwap.drag = null;
     this._previousSwap.delta = 0;
+    this._scrollXOffset = 0;
+    this._scrollYOffset = 0;
   }
 
   /**

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular CDK - issue with scrolling and dragging element ...
Start dragging an item. Scroll the page; Drag item a bit more when not scrolling. Effect: item placeholder stays in wrong place and...
Read more >
Cdk Drop List Scroll - StackBlitz
Dependencies · 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8.
Read more >
5 Things I wish I knew about the CDK's Drag & Drop
Every element you want to be draggable or to be a drop target MUST be the child of a cdkDropList. The name DropList...
Read more >
Angular 7 - Virtual Scrolling and Drag and Drop features
Virtual Scrolling loads and unloads elements from the DOM based on the visible parts of a list, where Drag and Drop feature supports ......
Read more >
Drag and Drop | Angular Material
To restrict dragging to a specific axis, you can set cdkDragLockAxis on cdkDrag or cdkDropListLockAxis on cdkDropList to either "x" or "y" ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found