I've been banging my head against the wall trying to figure this out. I found an example of pretty much exactly what I'm trying to do via the Sortable.js library repo here but I haven't been able to implement it using Vue.Draggable.
My theory of how to do it is add a <draggable/>
element that is in the same group
as the rest of the elements and listen for an @add
event on it, then remove that dragged element from its list.
One gotcha (maybe) is I'm trying to designate a "trash" button as the removal region, and if it references the same draggable group
, that dragged element gets appended to the button group and throws off the whole UI. So, a really important thing as that there's some sort of user feedback (e.g. trash icon turns red when hovering with drag element), but the dragged element shouldn't get inserted to the button group.
Initial Drag State
Intended Delete Action
Thanks in advance!
Lets solve some of the problems in turn:
How do I let a trash draggable accept any group
The answer to that is to set the pull
and push
of the group attribute.
trashOptions: {
group: {
name: 'trash',
draggable: '.dropitem',
put: () => true,
pull: false
}
}
By setting put
to a function that always returns true, it will accept any group. Alternatively you can set it to an array with groups you accept from.
How do I prevent my button from being messed up when setting it as a draggable area
The easiest way is to set the inserted item to display: none
. You can simply hide whatever you set as the draggable
attribute, or use the ghostClass
setting (as per the documentation).
How do I give the user feedback?
This one is tricky. Draggable does not set a class on the draggable area you are using. You can however use a smart css selector to sort-of achieve what you want. First we define a footer.
<draggable v-model="trashZone" class="dropzone trashzone" :options="trashOptions">
<div slot="footer" class="footer">Trash</div>
</draggable>
We position this absolute to the dropzone and make sure it covers the entire thing. Dropped elements will now always appear before the footer. This is great, because we can use the next-selector (+
) to select the footer after the inserted dropitem, and apply different styling. In this case we apply a red background and make the text white.
.trashzone .footer {
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.trashzone .dropitem + .footer {
background: red;
color: white;
}
A full working example is available on codesandbox.