-
-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Managing state when moving items between lists #23
Comments
For context, here is the problem in action: |
Thanks for the detailed issue + repro! I'll try and investigate tonight or tomorrow and will respond back here |
If you compare the approach of another library they also seem to remove the item onDragAdd manually, allowing for the component to render its own with v-for. I dont think sortableJS provides any options for renderless listing. |
Thanks for the info, @Chuuone. I got a little caught up with work and haven't worked on this yet, but that's very helpful. |
Thank you @Chuuone - that's what we decided to do in the end :) |
I'm facing kind the same behavior, with <draggable
:component-data="{name:'fade', type: 'transtion-group'}"
v-model="modules" group="modules"
item-key="module"
class="q-pa-md row items-start q-gutter-md"
:move="test"
@start="dragging = true"
@end="dragging = false"
v-bind="dragOptions"> <Sortable
:list="modules"
item-key="module"
:options="options"
class="q-pa-md row items-start q-gutter-md"
group="modules"> |
@goldyfruit are your |
I am also having the same issue. In my case, when I move an item between lists I am removing and adding it in the database, which then reflects the state of the lists. As above my state reflect it correctly, hoverer Sortable duplicates the item in list. Firstly it creates some ghost item with draggable="false" and then my proper item is added which makes two same items at the end. |
@jakubserwin any API suggestions on how you would like to interact with the lib would be welcome. I use it in a stateless context so I don't need to keep it in-sync besides on load. |
@MaxLeiter - I wonder if supporting this fork of sortable would enable folks to manage state better? I have been looking into this as I am experiencing another issue where the DOM and state get out of sync (when adding an item to the list after drag and drop it is added in the wrong place). I tried to create a fork of your library but got stuck. I would be happy to work through this with you if you think it is a viable option for the lib. |
I have the same problem. When I use the method to manage the data in pinia, it will affect the sorting of DOM. It is a similar problem to this issue vueuse/vueuse#2924 |
Anyone got a solution to this yet? |
Sorry @nlhkabu, I completely missed your offer. It's probably too late to be of help for you, but that fork seems like a great solution with the caveat of multidrag not working. I intend to look into it soon |
I'm personally just including the group (not the sortable group, but a key of mine, mostly group / index) in the remove and add methods, don't use the other ones. <Sortable :list="itemsA"
group="same"
@add="(event) => handleAdd(event, 'a')"
@remove="(event) => handleRemove(event, 'a')"
@end="(event) => handleEnd(event, 'a')"
>
...
</Sortable>
<Sortable :list="itemsB"
group="same"
@add="(event) => handleAdd(event, 'b')"
@remove="(event) => handleRemove(event, 'b')"
@end="(event) => handleEnd(event, 'b')"
>
...
</Sortable> Now when you move an item from list a to b -> handleAdd is called with "b" and handleRemove is called with "a".. Alternatively you can get the html item from event.item too (Check SortableEvent).. (Add a data attribute or something to match it easily) and update the store accordingly.. Not sure if there is an easier way @MaxLeiter? P.S.: handleEnd is for sorting the list in this sample. |
I'm experiencing the same issue where I have two separate When I move an item between the two lists the item is removed from the previous parent but is then duplicated in the new parent list. I managed to get around this by listening to the async function moveItem(event: { newIndex: number | undefined, oldIndex: number | undefined, item: HTMLElement, to: HTMLElement, parentId: string }) {
const op = {
type: EditorOperationType.MOVE,
fromIndex: event.oldIndex,
toIndex: event.newIndex,
fromParentId: parentItem.item.itemId,
toParentId: destinationParentItem.item.itemId,
item: draftItem.item,
itemId: draftItem.item.itemId,
} as MoveOperation
myStore.addOperation(op)
event.item.remove() <- here
}
<template>
<Sortable
:list="myStore.state.list"
item-key="id"
:options="{
handle: '.grab-handle',
group: {
name: 'items',
},
}"
class="flex flex-col gap-2"
:data-id="itemId"
@end="(event) => moveItem(event)"
>
<template #item="{ element: item }">
<div :id="item.id class="flex items-center" :data-id="item.id>
<div :key="item.id" class="draggable grab-handle">
<div>
<Icon name="mdi:drag" class="cursor-move size-5 text-gray-500" />
</div>
</div>
<div class="flex-1">
{{ item.id }}
</div>
</div>
</template>
</Sortable>
</template> update This is still an issue it seems. update 2 |
Further update to this - when using |
Thanks again for this lib.
I have several lists on my page, and want to be able to drag items between lists. For this, I give every list the same sortable
group
option.This is how I am trying to manage the state when dragging an item between lists:
remove
event to remove item from the stateadd
event to add the item back to the state in its new locationMy state is updating just fine, however, the orginal DOM element is moved to the new list (and not removed from the DOM). This results in duplicates (because my state also creates a new element).
Currently, it looks like my options are to either:
event.item.remove()
ORBoth of these seem hacky - is there a better approach?
The text was updated successfully, but these errors were encountered: