I am using Vue 2 with Bootstrap Vue. I have a table for which I would like to be able to drag and drop these rows. But the way I implemented it does not work, but I don't know why. I am guessing the table structure messes things up, that's the only idea of mine. Here is the code:
I am using Vue 2 with Bootstrap Vue. I have a table for which I would like to be able to drag and drop these rows. But the way I implemented it does not work, but I don't know why. I am guessing the table structure messes things up, that's the only idea of mine. Here is the code:
<b-overlay
:show="loading"
rounded="sm"
spinner-variant="primary"
>
<draggable
v-model="accounts"
@end="onDragEnd"
tag="tbody"
:move="onMove"
:handle=".handle"
>
<b-table
:fields="fields"
:items="accounts"
responsive
head-variant="light"
tbody-tr-class="item"
>
<template #head(handle)="data">
{{ '' }}
</template>
<template #cell(handle)="data">
<div class="handle-container">
<i class="fa fa-align-justify fa-lg handle"></i>
</div>
</template>
<template #cell(icon)="data">
<b-card
class="my-2"
:style="{ 'background-color': data.item.color }"
>
<b-card-sub-title>
<span v-html="getIcon(data.value)"></span>
</b-card-sub-title>
</b-card>
</template>
<template #cell(name)="data">
<b>{{ data.value }}</b>
</template>
<template #cell(balance)="data">
<span><i class="fas fa-euro-sign"></i> {{ data.value.toFixed(2) }}</span>
</template>
<template #cell(actions)="data">
<span class="cursor-pointer" v-b-modal="`bank-account-${data.item.id}-edit-modal`">
<i class="fas fa-edit fa-lg"></i>
</span>
<modal
:id="`bank-account-${data.item.id}-edit-modal`"
:title="$t('actions.edit-bank-account')"
:ok-disabled="!canSubmit"
@ok-pressed="$refs.form.submit()"
>
<add-bank-account-form
ref="form"
:can-submit="canSubmit"
:id="data.item.id"
@form-updated="updateFormValidity"
@item-added="payload => itemUpdated(payload, data.item.id)"
/>
</modal>
<span class="cursor-pointer trash-icon" @click="deleteItem(data.item.id)">
<i class="fas fa-trash fa-lg"></i>
</span>
</template>
</b-table>
</draggable>
</b-overlay>
import { mapGetters } from 'vuex';
import Request from '@/mixins/Request';
import draggable from 'vuedraggable';
export default {
components: {
draggable,
},
mixins: [
Request,
],
data() {
return {
loading: false,
accounts: [],
canSubmit: false,
fields: [
{ key: 'handle', label: this.$t('misc.handle') },
{ key: 'icon', label: this.$t('misc.type') },
{ key: 'name', label: this.$t('misc.name') },
{ key: 'balance', label: this.$t('misc.balance') },
{ key: 'lastUpdate', label: this.$t('misc.last-update') },
{ key: 'actions', label: this.$t('misc.actions') },
],
};
},
computed: {
...mapGetters({
activeUser: 'getActiveUser'
}),
},
watch: {
activeUser(newVal) {
if (newVal) {
this.getBankAccounts();
}
},
},
methods: {
async getBankAccounts() {
this.loading = true;
const { response } = await this.request('GET', '/bank-accounts', { params: { userId: this.activeUser.id, page: 1, perPage: 999 } });
this.loading = false;
this.accounts = response.data.data.map(account => ({
id: account.id,
handle: '',
icon: account.accountType.icon,
name: account.name,
balance: account.amount,
lastUpdate: account.updated_at ?? '-',
color: account.color,
actions: '',
}));
},
getIcon(icon) {
return `<i class="${icon} text-white fa-3x"></i>`;
},
updateFormValidity() {
if (this.$refs.form) {
this.canSubmit = Object.values(this.$refs.form.item).every((value) => value);
} else {
this.canSubmit = false;
}
},
itemUpdated(data, bankAccountId) {
this.$bvModal.hide(`bank-account-${bankAccountId}-edit-modal`);
this.$toast.success(this.$t('messages.bank-account-updated'));
this.getBankAccounts();
},
async deleteItem(id) {
await this.request('DELETE', `/bank-accounts/${id}`);
this.$toast.success(this.$t('messages.bank-account-deleted'));
this.getBankAccounts();
},
onDragEnd() {
// Handle the drag end event if you want to perform any actions
// after the dragging is complete, such as saving the new order.
console.log('Drag ended:', this.accounts);
// Optionally, save the new order to the backend here.
this.saveNewOrder();
},
onMove(evt, originalEvent) {
// Additional logic to determine if a move is allowed
// return true if allowed, false otherwise.
return evt.from === evt.to; // Allow only within the same table
},
saveNewOrder() {
// Here you would implement the logic to save the new order to the server
console.log('New order saved:', this.accounts);
// For example, you might make an API call to update the order
this.request('PUT', '/bank-accounts/order', { data: this.accounts });
},
},
};