While working on one of my projects, I encountered a particular task that required a unique solution. Despite finding similar solutions on stackoverflow, none seemed to work for me. The key aspect that was missing from those solutions is the importance of providing the Sortable-object with the dataIdAttr property and setting a relevant attribute in the children of the sortable-dom-element. This step is crucial when dealing with a bootstrap-vue table as it enables you to rearrange rows and update vue-reactive-data based on the changed drag indexes.
I believe this information could be helpful for someone facing a similar challenge.
<template>
<b-table
v-draggable-rows="{ data: items, orderColumn: '№' }"
:items="items"
>
<template #cell(Dragger)>
<IconDragHandle />
</template>
</b-table>
</template>
<script>
import IconDragHandle from '~/components/icons/table/IconDragHandle.vue';
export default {
components: {
IconDragHandle,
},
data() {
return {
items: [],
};
},
created() {
this.items = [...Array(8).keys()].map(x => ({
'Dragger': '',
'№': x + 1,
'Cell1': x + 1,
'Cell2': x + 1,
'Cell3': x + 1,
}));
},
};
</script>
import Vue from 'vue';
import Sortable from 'sortablejs';
Vue.directive('draggable-rows', {
bind(el, binding, vnode) {
const table = el;
table._sortable = createSortable(
table.querySelector('tbody'),
binding.value,
vnode
);
},
});
const createSortable = (el, options, vnode) => {
let order = [];
const data = options.data;
const orderColumn = options.orderColumn;
for (let i = 0; i < el.children.length; i++) {
el.children[i].setAttribute('sortable-id', i);
}
return Sortable.create(el, {
dataIdAttr: 'sortable-id', // default: data-id
animation: 150,
easing: 'cubic-bezier(0.25, 1, 0.5, 1)',
handle: '.custom-table-draggable-handle',
ghostClass: 'custom-draggable-rows-ghost',
chosenClass: 'custom-draggable-rows-chosen',
dragClass: 'custom-draggable-rows-drag',
onStart() {
order = [...this.toArray()];
},
onEnd(evt) {
this.sort(order);
data.splice(evt.newIndex, 0, ...data.splice(evt.oldIndex, 1));
if (!orderColumn) return;
data.forEach((o, i) => {
o[orderColumn] = i + 1;
});
},
});
};
Draggable Draggable.Vue Bootstrap-Vue SortableJS v-sortable Reorder