vue-draggable-plus
vue-draggable-plus copied to clipboard
[Feature request] - Add static items inside vDraggable component
Hello, Im dealing with kinda tricky problem.
I want to use <table> and make <tr> in thead draggable, but i must have first and last columns fixed.
I can disable dragging on first/last item, but all other draggable items can be moved there because <tr> is still draggable.
I did not find solution to deal with this in documentation.
I have also found solution in VueDraggableNext https://github.com/SortableJS/vue.draggable.next with header and footer slot (and tried it, it works). It would be lovely to have it there, because I found your solution to be better and more up to date.
This is example how I guess it should be working:
In static regions draggable options should be completely deactivated, even if it is inside
<draggable
v-model="list"
handle=".column__content__handle"
tag="tr"
@end="onEnd"
>
<!--region static-->
<td class="staticBefore"></td>
<!--end region static-->
<!--region draggable-->
<td v-for="item in list" :key="item.id" :class="item.name" class="item">
{{ item.name }}
</td>
<!--end region draggable-->
<!--region static-->
<td class="staticAfter"></td>
<!--end region static-->
</draggable>
Here is also example of application:
All is in one <tr> but first two columns has to be there, no matter what..
Use the target property to select the container with draggable items.
<draggable
v-model="list"
handle=".column__content__handle"
tag="tr"
@end="onEnd"
target=".draggable"
>
<td class="staticBefore"></td>
<!--region draggable-->
<section class="draggable">
<td v-for="item in list" :key="item.id" :class="item.name" class="item">
{{ item.name }}
</td>
</section>
<!--end region draggable-->
<td class="staticAfter"></td>
</draggable>
https://vue-draggable-plus.pages.dev/en/demo/target-container/
I didn't have time to test this until today because our team has been busy, and our previous solution using draggable-next was working reasonably well. However, we now want to improve it.
An additional issue (which I hadn't mentioned before) is that we're using Vuetify 3's VDataTable, which renders its own internal table structure and classes. Injecting a <section> (or any wrapper element) into the markup breaks Vuetify's behavior — especially within <tr> elements.
Thanks to the hint from @Mihailoff, I found a working solution using display: contents. This allows us to preserve a logical wrapper (.draggable class) without introducing any actual DOM node that would interfere with Vuetify.
<vue-draggable
v-model="list"
handle=".column__content__handle"
tag="tr"
target=".draggable"
@end="onEnd"
>
<th class="staticBefore"></th>
<!-- Draggable content region (no actual wrapper rendered) -->
<section
class="draggable"
style="display: contents"
>
<th
v-for="item in list"
:key="item.id"
:class="item.name"
class="item"
>
{{ item.name }}
</th>
</section>
<th class="staticAfter"></th>
</vue-draggable>