SortableJS / vue.draggable.next

Vue 3 compatible drag-and-drop component based on Sortable.js
https://sortablejs.github.io/vue.draggable.next/#/simple
MIT License
3.91k stars 531 forks source link

Dragged item is placed below footer #108

Open iliubinskii opened 2 years ago

iliubinskii commented 2 years ago

Jsfiddle link

https://sortablejs.github.io/vue.draggable.next/#/two-list-headerslots

Step by step scenario

The above link points to your demo.

Try to drag item from the second list to the first list from below. I am doing this in FF. Here is the result: Screenshot

Note that "Jonny 4" is under the footer. I think this is not right.

After I drop item it is placed correctly

boboldehampsink commented 2 years ago

Also seeing this issue

OneFourFree commented 2 years ago

Same, is there a workaround for this?

spixy commented 2 years ago

also have this issue, for now no workaround found

radek-altof commented 1 year ago

Same here 😕 This needs to be fixed.

In the meantime, I have a small workaround - register the :move="onMove" callback on the draggable element. Assuming that footer is always present and one element only.

async function onMove (e) {
    // Wait for DOM to be updated
    await nextTick();

    // Move the element before footer if needed
    if (e.to.lastElementChild === e.dragged) {
        e.to.removeChild(e.dragged);
        e.to.insertBefore(e.dragged, e.to.lastElementChild);
    }
}
vaheqelyan commented 1 year ago

any updates on this ?

vaheqelyan commented 1 year ago

Same bug happens here https://sortablejs.github.io/Vue.Draggable/#/footerslot (SortableJS/Vue.Draggable)

https://user-images.githubusercontent.com/14107127/220333225-af33c8d7-0100-470b-8481-548516db7a87.mp4

chris-mackie commented 1 year ago

If anyone else if having an issue, this solution worked for me:

 function fixFooter(e) {
      if (e.relatedContext.list.length === e.draggedContext.futureIndex) {
        let newListDom = e.to

        let newListFooter = e.to.lastChild
        nextTick(() => {
          newListDom.appendChild(newListFooter);
        });
      }else {
        let currentListDom = e.from;
        let currentListFooter = e.from.lastChild;
        nextTick(() => {
          currentListDom.appendChild(currentListFooter);
        });
      }
    }

Then add :move="fixFooter" to your draggable element.

webskimajster commented 6 months ago

There is also another solution for this without using JavaScript, which works better if we want to use a transition effect. The previous solutions do not work properly with transitions; the footer jumps instead of transitioning smoothly.

My solution was to set the parent's display property to display: flex. Then, I added order: 1 to all child elements, but for the footer element, I added order: 2. This simple workaround works like a charm for me.