Reputation: 177
I am asking for some assistance resolving an issue I have been scratching my head on for a few days now.
Problem
I am currently trying to implement a drag-and-drop feature that requires you being able to drag up to 10 items to fill in designated spots (spots are only allowed to hold 1 item) and after the 10 are filled, the options will then not allow any more dragging until a spot is cleared.
I am currently using the Ngx-Smooth-DND library for my drag-and-drop, but I am not limited to this and can be open to a different library if it can meet the requirements (including Kendo Sortable which I have a license for).
Where I am struggling is that drag-and-drop allows more than one item to go into a list/zone, whereas I am wanting to only allow a single item in a zone at a time. Imagine a drag-and-drop quiz where you can drag an answer to only one spot on a diagram, and once you have one there the only thing you can do is either replace it by dropping another item or not allow anything else to be dropped until you clear the space.
Requirements
Needing to implement a drag-and-drop requirement where you can drag items from a list of options and drop them into 1 of 10 different zones.
Code Example
I am pasting a Stackblitz showing what I am going for and I am also going to link the Ngx-smooth-dnd library github for documentation:
https://stackblitz.com/edit/angular-ro3pyw
https://github.com/kutlugsahin/ngx-smooth-dnd
Bonus
If there is a better approach or better drag-and-drop library that can accomplish this much cleaner and simpler, I am 100% open to options.
Upvotes: 1
Views: 3593
Reputation: 7451
I have used angular material: https://material.angular.io/cdk/drag-drop/overview To create something similar.
I used this example: https://material.angular.io/cdk/drag-drop/overview#controlling-which-items-can-be-moved-into-a-container to figure out how to limit the number of items which could exist in a container:
// drop-example.component.html
<div class="drop-area" cdkDropList
#dropArea="cdkDropList"
[cdkDropListData]="myEmptyArrayVariable"
[cdkDropListConnectedTo]="[optionsList]"
(cdkDropListDropped)="drop($event)"
[cdkDropListEnterPredicate]="limiterPredicate">
// drop-example.component.ts
import { CdkDragDrop, moveItemInArray, transferArrayItem, CdkDrag, CdkDropList } from '@angular/cdk/drag-drop';
...
// see section in the drag-drop docs for example drop($event) {} function
...
limiterPredicate(item: CdkDrag, container: CdkDropList) {
if (container.data.length === 0) {
return true;
} else {
return false;
}
}
If you can't work out the rest, then I can try and create a stackblitz for you, just let me know!
Upvotes: 2