Alfred-Skyblue / vue-draggable-plus

Universal Drag-and-Drop Component Supporting both Vue 3 and Vue 2
https://vue-draggable-plus.pages.dev/en/
MIT License
2.72k stars 106 forks source link

Target and Item - how to? #51

Open aeruggiero opened 9 months ago

aeruggiero commented 9 months ago

Hi all, I've been looking everywhere but it seems not possible to get info regarding the item being dragged, the source and the destination at the same time. I have a situation like this:

<script setup lang="ts">
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue";
import { Head, router } from "@inertiajs/vue3";
import { ref } from "vue";
import { VueDraggable } from "vue-draggable-plus";
const props = defineProps<{
    orders: App.Models.Order[];
    statuses: App.Models.Status[];
}>();
const statusOrders = ref([] as App.Models.Order[][]);
props.statuses.forEach((status) =>
    statusOrders.value.push(
        props.orders.filter((order) => order.status_id == status.id)
    )
);

defineOptions({ layout: AuthenticatedLayout });

function handleDrag(item: App.Models.Order) {
    statusOrders.value.forEach((el, index) => {
        if (el.map((e) => e.id).indexOf(item.id) >= 0) {
            item.status_id = props.statuses[index].id;
            router.patch(`/order/${item.id}`, item as Record<string, any>);
        }
    });
}
</script>

<template>
            <div
                class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg flex"
            >
                <div v-for="(status, index) in statuses">
                    {{ status.name }}
                    <VueDraggable
                        class="flex flex-col gap-2 p-4 w-300px h-300px m-auto bg-gray-500/5 rounded overflow-auto"
                        v-model="statusOrders[index]"
                        :animation="150"
                        ghostClass="ghost"
                        group="people"
                        :key="status.id"
                        :id="'status' + index"
                        tag="div"
                    >
                        <div
                            v-for="item in statusOrders[index]"
                            :key="item.id"
                            class="cursor-move h-30 bg-gray-500/5 rounded p-3"
                            @dragend="handleDrag(item)"
                        >
                            {{ item.code }}
                        </div>
                    </VueDraggable>
                </div>
            </div>

</template>

As you can see, I need to update the order status depending on where I drag the item. If I had the target div ID, I would be able to immediately retrieve the corresponding status. However, currently, the only way is to loop through the array and check for the dragged item. Additionally, the only way I can obtain the item is by using the 'ondragend' event on the dragged item.

Do you have any suggestions? Am I doing something wrong?

Thanks

Alfred-Skyblue commented 8 months ago

You can pass the onEnd event to VueDraggable and obtain element information from the event object.

<template>
                 <VueDraggable
                        v-model="statusOrders[index]"
                        :animation="150"
                        ghostClass="ghost"
                        group="people"
                        :key="status.id"
                        :id="'status' + index"
                        tag="div"
                        @end="onEnd"
                    >
                        <div
                            v-for="item in statusOrders[index]"
                            :key="item.id"
                            class="cursor-move h-30 bg-gray-500/5 rounded p-3"
                            @dragend="handleDrag(item)"
                        >
                            {{ item.code }}
                        </div>
                    </VueDraggable>

</template>
<script setup>

function onEnd(e){
   console.log(e)
}
</script>