I'm trying to drag items across two lists. The bottom list is a typical sorted list (like an "inventory"), but I want the top items to be unsorted and droppable anywhere (like a "game board").
I have it MOSTLY working, however when dropping into the top box event.currentIndex is always 0. But when dragging out from there I get different event.previousIndex values, which means the model and DOM elements don't always match.
Here's a stackblitz showing what I mean. Drag a few items into the top box and play around with it, you'll notice sometimes the wrong item gets moved.
It's most notable when you interact in reverse order, for example:

cdkDropListSortingDisabled option only works when moving items within the same container. If you move from one container to another then Angular sorts position of blocks:
this._itemPositions = this._activeDraggables.map(drag => {
const elementToMeasure = drag.getVisibleElement();
return {drag, offset: 0, clientRect: getMutableClientRect(elementToMeasure)};
}).sort((a, b) => {
return isHorizontal ? a.clientRect.left - b.clientRect.left :
a.clientRect.top - b.clientRect.top;
});
Since you didn't provide orientation and default is vertical then it is sorted by top position.
The top box event.currentIndex is always 0 because you use absolute positioning and placeholder is always at the top.
Try adding the following style to see where the placeholder is displayed:
.cdk-drag-placeholder {
opacity: 1;
background: red;
}

To fix it you can calculate currentIndex by yourself, e.g. like this:
const isWithinSameContainer = event.previousContainer === event.container;
let toIndex = event.currentIndex;
if (event.container.sortingDisabled) {
const arr = event.container.data.sort((a, b) => a.top - b.top);
const targetIndex = arr.findIndex(item => item.top > top);
toIndex =
targetIndex === -1
? isWithinSameContainer
? arr.length - 1
: arr.length
: targetIndex;
}
const item = event.previousContainer.data[event.previousIndex];
item.top = top;
item.left = left;
if (isWithinSameContainer) {
moveItemInArray(event.container.data, event.previousIndex, toIndex);
} else {
transferArrayItem(
event.previousContainer.data,
event.container.data,
event.previousIndex,
toIndex
);
}
Forked Stackblitz
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With