vue.draggable dragging wrong element

3.9k Views Asked by At

I'm trying to reorder the colors in a palette using DnD. Pen is here: - https://codepen.io/neon22/project/editor/XbqvYe

<script type="text/x-template" id="cpalette">
  <div>
    <draggable v-model="colors" class="dragArea">
        <ul class="color-list" >
            <input type="hidden" :name="inputId" :id="inputId" v-model="colors">
            <li v-if="emptyOption">
                <a class="noColor" v-if="emptyOption !== 'true'" href="" @click.prevent="setColor();" :title="emptyOption === 'true' ? '' : emptyOption" :class="{selected: !selectedColor && !noSelection}"></a>
            </li>
          <!-- <draggable v-model="colors" tag='li' class="dragArea"> -->
            <li v-for="color in colors" :key="color.id" :data-id="color.id" >
                <a href="" :style="{background: color.hex}" :title="color.stash" @click.prevent="setColor(color.hex, color.id, color.stash)" :class="{selected: selectedColor === color.hex}"></a>
            </li>
          <!-- </draggable> -->
        </ul>
    </draggable>
  </div>
</script>

I.e. I'm reordering in the same array. (I also want to enable dropping it into a separate region for copying etc). Instead I can drag the entire UL but not the individual li elements. I have noodled with it for a while now and have confused myself. I can see classes changing in chrome dev so I think its almost working. Maybe the input is getting in the way ?

I'm trying to get an end result like this: - https://sortablejs.github.io/Vue.Draggable/#/transition-example-2 but I have not added the transition-group yet.

I will also want to be able to drop the individual colors into a second area (where a @dropend will copy them and etc etc...) In fact if I can get a better grip on draggable then maybe I'd do a delete trashcan instead of a button.

So I want to reorder individual colors and enable a separate drop target.

Any help would be greatly appreciated. I'm sure its something simple :(

1

There are 1 best solutions below

2
On

The elements that you intend to be draggable should be direct children of draggable component or wrapped around with transition-group.

But in your case, the only child of draggable is the unordered list which is the parent of the list of elements you intend to be draggable.

Simply uncommenting the draggable tag around the list of colours.

        <ul class="color-list" >
            <input type="hidden" :name="inputId" :id="inputId" v-model="colors">
            <li v-if="emptyOption">
                <a class="noColor" v-if="emptyOption !== 'true'" href="" @click.prevent="setColor();" :title="emptyOption === 'true' ? '' : emptyOption" :class="{selected: !selectedColor && !noSelection}"></a>
            </li>
          <draggable v-model="colors" class="dragArea" group="color-stuff">
            <li v-for="color in colors" :key="color.id" :data-id="color.id" >
                <a href="" :style="{background: color.hex}" :title="color.stash" @click.prevent="setColor(color.hex, color.id, color.stash)" :class="{selected: selectedColor === color.hex}"></a>
            </li>
          </draggable>
        </ul>

Now, about enabling dragging the colors to a new area for copying or deleting:

The thing with sortable (which the vue draggable is based on) is that you can drag items in a sortable list within the list (to reorder) or you can move the item to another sortable list within the same group.

So, you can either create another draggable component with the group parameter set to the same value as the draggable component containing the colours, then override the @end or @remove methods so that when you move a colour from the colour-list to the second draggable area, the colour that is removed from the first list is copied back to it (which is quite hacky)

or you could simply use Html5 Drag and Drop like so:

<draggable v-model="colors" tag='li' class="dragArea">
    <li v-for="color in colors" 
        :key="color.id" 
        :data-id="color.id" 
        draggable='true'        
        @dragstart="functionToHandleDragStart" 
    >
          <a href="" 
        :style="{background: color.hex}" 
        :title="color.stash" 
        @click.prevent="setColor(color.hex, color.id, color.stash)" 
        :class="{selected: selectedColor === color.hex}"
          >
          </a>
    </li>
</draggable>

<div
    @drop="functionToHandleDrop"
    @dragover="(event)=>{event.preventDefault()}"
>
        <p> drop target </p>

</div>