Vue.Draggable icon indicating copy to clipboard operation
Vue.Draggable copied to clipboard

The ghost-class is not working consistently

Open huynl-96 opened this issue 3 years ago • 10 comments

Reproduce Link

https://sortablejs.github.io/Vue.Draggable/#/transition-example-2

Step by step scenario

  1. Click on any item on the list.
  2. Drag and drop that item in a new place.
  3. Repeat step 1 and 2 a several times.

Actual

At first, the targeted item ghost class is working correctly (you can see a darker background of the targeted element). But after repeating step 1 and 2 about 3~4 times, the darker background disappeared.

Expected

The darker background stays consistently whenever dragging the targeted item.

Demo:

https://user-images.githubusercontent.com/15758406/119925876-75fb2d00-bfa0-11eb-989a-94309ceee834.mov

huynl-96 avatar May 28 '21 03:05 huynl-96

Same here.

I did some testing and found the following:

  • It only happens when you use animations.

  • It only happens if the element has changed it's position at least once, if you just move the element around and put it back at the same place, the ghost will always work.

  • If the element has no ghost, picking it up and dropping it in the same place will fix it, but only for the current position, if you move it to a different one it will happen again.

  • When the error happens, the "sortable-chosen" class gets assigned when you click, but it will disappear as soon as you start to move the element and the "ghost" class doesn't get assigned at all.

xWinuX avatar Jul 22 '21 14:07 xWinuX

I think there's a misunderstanding.

The problem isn't the animation, the problem is that the ghost class doesn't get applied consistently. The element that doesn't work is the one in the list not the one that the cursor is "holding" see picture below.

image

If you look at the video you can see that the dragged element gets a bit transparent when its being moved (ghost class gets applied) like above, but after the third drag it stops working and just stays the same.

xWinuX avatar Aug 04 '21 11:08 xWinuX

@xWinuX Hi, have you found out a way to work around the problem? This problem seems to exist only if you wrap a transition-group around the draggable elements.

andyrochi avatar Aug 25 '21 03:08 andyrochi

I'm also having trouble getting consistent results from ghost-class, but haven't used any animations or transition-group. Just a plain Draggable component with :group and some listeners set.

An issue in SortableJS describes that it related to the order of css classes, and hasn't yet been confirmed fixed as far as I'm aware. https://github.com/SortableJS/Sortable/issues/1795

I'm trying to set the d-none class from vuetify, while this worked in our previous build, it doesn't work anymore with no apparent explanation or changes.

Excalibaard avatar Oct 06 '21 10:10 Excalibaard

Also running into this issue with the Vue 3 version. Ghost class is consistently not being applied.

adamreisnz avatar Dec 18 '21 07:12 adamreisnz

I think the problem in my case is being manifested when applying dynamic classes through vue CSS modules. It's possible the ghost class is applied by Sortable, but then Vue applies the dynamic classes, which then removes the ghost class.

Will see if I can manually apply the ghost class by listening to start/end drag events.

Edit: Yep that was in fact the problem. Solved by implementing a wrapper div for the draggable items, so that the ghost class could be applied on the parent div, while the dynamic classes could be applied on the child elements.

adamreisnz avatar Dec 18 '21 21:12 adamreisnz

I had the same issue, I ended up using [draggable="true"]instead as a workaround

yassinya avatar Jan 25 '22 10:01 yassinya

I'm also having trouble getting consistent results from ghost-class, but haven't used any animations or transition-group. Just a plain Draggable component with :group and some listeners set.

An issue in SortableJS describes that it related to the order of css classes, and hasn't yet been confirmed fixed as far as I'm aware. SortableJS/Sortable#1795

I'm trying to set the d-none class from vuetify, while this worked in our previous build, it doesn't work anymore with no apparent explanation or changes.

The linked issue addresses a different problem where the css styles of applied classes overwrite each other. In our case here the class "sortable-ghost" (or the class defined in ghost-class) isn't applied in the first place.

s4b2x avatar Oct 13 '22 11:10 s4b2x

I had the same issue, I ended up using [draggable="true"]instead as a workaround

The problem with this workaround is that the style is applied to the "virtual" element anchored to the mouse, too. In my case, I want the slot (where the element would "fall" into) to appear empty, so I set opacity: 0 in the ghost-class. This makes the "virtual" element invisible too. I'm afraid this is a timing problem. [draggable="true"] is applied instantly while the ghost-class gets added after a short timeout.

s4b2x avatar Oct 13 '22 11:10 s4b2x

I think the problem in my case is being manifested when applying dynamic classes through vue CSS modules. It's possible the ghost class is applied by Sortable, but then Vue applies the dynamic classes, which then removes the ghost class.

Will see if I can manually apply the ghost class by listening to start/end drag events.

Edit: Yep that was in fact the problem. Solved by implementing a wrapper div for the draggable items, so that the ghost class could be applied on the parent div, while the dynamic classes could be applied on the child elements.

That doesn't work for me. Instead I go with your first idea (stripped to the essential parts):

<draggable
  @start="dragging = true"
  @end="dragging = false"
>
  <transition-group
    class="row"
    :name="!dragging ? 'flip-list' : null"
    tag="div"
  >
    <v-col
      v-for="(element, index) in elements"
      :key="element.id"
      cols="2"
      @dragstart="addGhostClassFix"
    >
      draggable content
    </v-col>
  </transition-group>
</draggable>
addGhostClassFix(event) {
  /** Sometimes a bug in vue-draggable prevents the applying of the ghost class. */
  setTimeout(() => {
    if (event.target.draggable) {
      event.target.classList.add('sortable-ghost'); // if you use a different ghost-class, that must be used here as well, of course
    }
  }, 150);
}

(Edit: added if to function to prevent adding ghost class after element has been dropped)

s4b2x avatar Oct 13 '22 11:10 s4b2x