Reputation: 41
I'm trying to use vue-draggable with Vuetify v-data-table by following this article : https://medium.com/vuetify/drag-n-drop-in-vuetify-part-ii-2b07b4b27684
It says : "The main goal was to set tbody of table as draggable component and it was not possible because Vuetify uses template as a slot for rendering items."
After that, the guy found a solution with Sortable JS. I tried it but it's not working.
this error appears : Sortable: el must be an HTMLElement, not [object Function].
People are saying that Sortable JS is not working for Vue JS 2...
How can I do ?
If you have a solution please let me know :)
My code :
<v-data-table :headers="headers" :items="slots" :items-per-page="-1" ref="sortableTable" > <template v-slot:item="props"> <tr v-if="props.item.recipe" class="sortableRow"> <td style="text-align: center">{{props.item.slot}}</td> <td style="text-align: center" v-if="props.item.recipe.preferences"> <v-chip v-for="pref in props.item.recipe.preferences" :key="pref" small > {{ pref }} </v-chip> </td> <td style="text-align: center">{{props.item.recipe.protein}}</td> <td style="text-align: center">{{props.item.recipe.protein_cut}}</td> <td style="text-align: center">{{props.item.recipe.carb}}</td> <td style="text-align: center" v-if="props.item.recipe.tags"> <v-chip v-if="props.item.recipe.tags.indexOf('c3_appropriate') !== -1" small color="success" text-color="white" > C3 </v-chip> </td> <td style="text-align: center">{{props.item.recipe.ready_in}}</td> <td style="text-align: center"> <v-chip small :color="props.item.recipe.new_repeat === 'repeat' ? 'error' : 'success'" > {{ props.item.recipe.new_repeat }} </v-chip> </td> <td style="text-align: center"> {{ props.item.recipe.title + ' ' }} <span v-if="props.item.recipe.subtitle" style="font-size: 11px" > <br> {{ props.item.recipe.subtitle }} </span> </td> </tr> <tr v-else> <td style="text-align: center">{{props.item.slot}}</td> </tr> </template> </v-data-table> mounted() { let table = document.querySelector("table tbody"); console.log(table) const _self = this; Sortable.create(table, { draggable: '.sortableRow', handle: ".handle", onEnd({newIndex, oldIndex}) { const rowSelected = _self.slots.splice(oldIndex,1)[0]; _self.slots.splice(newIndex, 0, rowSelected); } }); }
Upvotes: 4
Views: 3629
Reputation: 2509
I'm using SortableJS with Nuxt. The shortest solution I found was to register a directive with Vue.directive
:
import Vue from 'vue'
import {Sortable} from 'sortablejs';
Vue.directive("sortableDataTable", {
bind(el, binding, vnode) {
const options = {
animation: 150,
onUpdate(event) {
vnode.child.$emit('sorted', event)
}
}
Sortable.create(el.getElementsByTagName('tbody')[0], options)
}
})
Now I can use the v-sortable-data-table
directive in a v-data-table
:
<v-data-table
v-sortable-data-table
:items="items"
:headers="headers"
item-key="id"
>
</v-data-table>
Note that the directive is registered as sortableDataTable
but is used as v-sortable-data-table
(camelCase is converted to kebab-case and must be prefixed with 'v-' when used).
Upvotes: 3