Index identified when using Angular Drag and Drop CDK is incorrect, causing misaligned order in array

682 Views Asked by At

The Environment

I have an Angular 15.2 app that is designed to build a 'photoshop-like' experience using the HTML Canvas.

I am attempting to use the Material Design Drag and Drop CDK found here to reorder element in an array which eventually I will use to control the layer order within the canvas.

As you can see from the HTML, I have a custom angular component that within contains the layout for one of the layers/blocks in the vertical list that you'll see further down in screenshots.

I have 4 items in an array, that is iterated over using *ngFor.

The Code

Here is the HTML for this:

<div class="layer-list" cdkDropList
        cdkDragPreviewContainer="parent" (cdkDropListDropped)="drop($event)">
            <div *ngFor="let layer of layerList" class="layer cdkdrag-box" cdkDrag>
                <app-existing-element-block class="individual-layer" [dataId]="layer.dataId" cdkDragBoundary=".layer-list"
                    [title]="layer.title" [type]="layer.type" [icon]="layer.icon"
                    (elementVisibilityChanged)="toggleElementVisibility($event)" (elementDeleted)="deleteElement($event)">
                </app-existing-element-block>
            </div>
        </div>

Here is the TS for controlling the detection of change in the drag/drop functionality:

drop(event: CdkDragDrop<string[]>) {
    if (event.previousIndex !== event.currentIndex) {
        const layersCopy = Array.from(this.layerList);
        console.log('event previous index:', +' ' + event.previousIndex);
        console.log('event current index:', +' ' + event.currentIndex);
        moveItemInArray(layersCopy, event.previousIndex, event.currentIndex);
        this.layerListService.updateLayers(layersCopy);
        this.getUpdatedLayerList();
    }
}

In the layer service, I have this:

updateLayers(layers: LayerElement[]) {
    this.layers = [...layers];
}

and the 'get updated layer list' does this:

getLayers(): LayerElement[] {
    return [...this.layers];
}

The Problem

When dropping item at index 0, to replace item at index 1, 2 or 3, Angular's Drag and drop CDK is reporting incorrect index numbers as to where it thinks the item is dropped.

For example, if I pick up item at index 0, and drop it over the top/in place of item at index 1, I get the following logs:

Before the ordering:
First Screenshot Before

Console Log:
First Log

After ordering:
First Screenshot After

The previous index is 1 where it should be 0, and the new/current index it thinks I'm trying to drop it at, is 2 higher than where it should be. It should be 1. As you can see, this also throws the ordering out completely.

Here's what we get if I drop the item at index 0, to index 2:

Before the ordering:
Second Screenshot Before

Console log:
Second Log

After ordering:
Second Screenshot After

As you can see, the index it thinks I'm trying to drop it at, is 4 higher than where it should be.

Further to this, the array of items therefore updates with the incorrect values, and reorders the items accordingly with the new order as you've seen in the above screenshots.

Any ideas?

0

There are 0 best solutions below