So I've recently started learning Svelte and I want to create a few lists where items can be dragged and dropped between them. Additionally, I would like to be able to sort / reorder the items within an individual list.
I've found this REPL https://svelte.dev/repl/b225504c9fea44b189ed5bfb566df6e6?version=3.50.1 which takes care of the between list functionality. But I'm at a loss of being able to drag and drop items in at specific indexes and to be able to sort them within a singular list as this just pushes the item to the end of the array.
Any help or direction would be much appreciated as I've never really worked with events, TIA
CodePudding user response:
You can annotate your items with identifying information and use the dragover
event to determine where exactly an item should land on drop.
E.g. add data
-attributes for the basket/item.
<div data-basket={basket.name} data-item={item} animate:flip>
Add a proper handler on the list of items:
<ul on:dragover|preventDefault={dragOver} ...>
Then update a local value with the target index, as determined by what the item is dragged over:
let dropIndex = null;
function dragOver(e) {
dropIndex = null;
const itemElement = e.target.closest('[data-item]');
if (itemElement == null)
return;
const { basket, item } = itemElement.dataset;
dropIndex = baskets.find(b => b.name == basket)
.items.indexOf(item);;
}
This then can be used to splice
in the new item, rather than just pushing it:
const items = baskets[basketIndex].items;
items.splice(dropIndex ?? items.length, 0, item);
baskets = baskets;
This is just a basic outline. To accurately implement a feature like this, you would have to also check the pointer position relative to what is being hovered to determine whether the insertion should be before or after the hovered item. Whether the item comes from the current basket might also be relevant.