Search code examples
angularangular-materialdrag-and-dropdraggableangular-cdk

Angular material drop event returns wrong index of dragged item and moves wrong item


Good afternoon,

I'm trying to setup two lists of chips which are draggable between two lists. The two variables availableActivationCountries and availableGroupCountries are filled by filtering another array, as shown below.

this.availableActivationCountries = this.brandCountries.filter(c => c.brandAvailable === true).sort((a, b) => (a.country < b.country ? -1 : 1));
this.availableGroupCountries = this.brandCountries.filter(c => c.brandAvailable === false).sort((a, b) => (a.country < b.country ? -1 : 1));

When I drag an item from the second list to the list above, a wrong index is returned in the drop event and a totally different item is moved.

If I fill the arrays with fixed data, it works as expected. So it has something to do with the filtering of brandCountries.

Does anyone has an idea on how to solve this?

component.ts

  dropCountry(event: CdkDragDrop<ICountry[]>) {
    console.log(event.item.element)
    console.log(event.previousContainer.data)
    //console.log(event.container.data[event.currentIndex].country)
    if (event.previousContainer != event.container) {
      transferArrayItem(event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex);

      this.availableActivationCountries.sort((a, b) => (a.country < b.country ? -1 : 1));
      this.availableGroupCountries.sort((a, b) => (a.country < b.country ? -1 : 1));

      console.log(this.availableActivationCountries);
    }
  }

component.html

<div cdkDropListGroup>
  <div cdkDropList [ngClass]="{'emptyDropArea' : availableActivationCountries.length == 0}" cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropCountry($event)" [cdkDropListData]="availableActivationCountries">
    <mat-chip-list id="activationCountries">
      <mat-chip cdkDrag selected *ngFor="let country of availableActivationCountries">
        <mat-chip-avatar>
          <img src="https://flagcdn.com/w20/{{country.country.toLowerCase()}}.png" width="20"/>
        </mat-chip-avatar>
        {{ country.country | translate }}
      </mat-chip>
    </mat-chip-list>
  </div>
  <!--  <h4>Available countries to add to Group</h4> -->
  <div cdkDropList [ngClass]="{'emptyDropArea' : availableGroupCountries.length == 0}" cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropCountry($event)" [cdkDropListData]="availableGroupCountries">
    <mat-chip-list id="availableCountries">
      <mat-chip cdkDrag *ngFor="let country of availableGroupCountries">
        <mat-chip-avatar>
          <img src="https://flagcdn.com/w20/{{country.country.toLowerCase()}}.png" width="20"/>
        </mat-chip-avatar>
        {{ country.country | translate }}
      </mat-chip>
    </mat-chip-list>
  </div>
  <h4>Inactive MyAccount countries</h4>
</div>

EDIT

I've tried to remove the filter on brandCountries. This doesn't change a thing. The amount of elements in the array may be the problem.

When the chip are in single line, it works properly.

enter image description here

It goes wrong from the moment that there are divided across multiple lines.

enter image description here


Solution

  • Removing the cdkDropListOrientation attribute solved my problem.