Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuetify TreeView + Drag and drop

I am trying to implement drag and drop on Vuetify Treeview and data table. It seems like it is not supported fully but a workaround is described in this thread. The workaround is however not complete. Perhaps the community would benefit if someone created a codepen or similar on this?

What confuses me is that the component DragDropSlot.vue is created but "drag-drop-slot" is used in the code. Also there is a "_.cloneDeep(this.tree)" call where _ is not defined. I assume it should be replaced by something. When I comment that out drag and drop does still not work. Probably missed something more like defining data. Not sure of correct data types. It seems to be based on react which I have not worked with. Have just started to learn vue and vuetify.

I'm open for any suggestion for how to solve this.

All the best

like image 748
Eric1101000101 Avatar asked Oct 24 '25 16:10

Eric1101000101


1 Answers

I use V-Treeview with Vue.Draggable (https://github.com/SortableJS/Vue.Draggable). I use direct link.

<script src="//cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0 vuedraggable.umd.min.js"/>
<v-treeview
:active.sync="active"
:items="users"
:search="search"
item-key="Id"
item-text="UserName"
item-children="Children"
:open.sync="open"
activatable
color="warning"
dense
transition
return-object
>
<template v-slot:label="{ item }">
<draggable :list="users" group="node" :id="item.Id" :data-parent="item.ParentId" @start="checkStart" @end="checkEnd"    >
    <label>
        <i class="fas fa-user mr-3" />
        <span id="item.id" >{{item.UserName}}</span>
    </label>  
</draggable>

Also I add ParentId property to item tree model: { Id:1, UserName: "John Doe", ParentId: null, Children:[{Id:2, ParentId: 1,...}] }
Then I use start and end events where I search parent start node from I drag the item and parent end node where I drop the item. When parent is null the item is a root.

new Vue({
        el: '#app',
        vuetify: new Vuetify(),
        components: {
            vuedraggable
        },
        data() {
            return {
                active: [],
                open: [],
                users: [],
                selectedItems: [],
            }
        },
        mounted: function () {
            this.fetchUsers();
        },
        methods: {
            findTreeItem: function (items, id) {
                if (!items) {
                    return;
                }
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    // Test current object
                    if (item.Id === id) {
                        return item;
                    }
                    // Test children recursively
                    const child = this.findTreeItem(item.Children, id);
                    if (child) {
                        return child;
                    }
                }
            },
            checkStart: function (evt) {
                var self = this;
                self.active = [];
                self.active.push(self.findTreeItem(self.users, evt.from.id))
            },
            checkEnd: function (evt) {
                var self = this;
                var itemSelected = self.active[0];
                var fromParent = itemSelected.ParentId ? self.findTreeItem(self.users, itemSelected.ParentId) : null;
                var toParent = self.findTreeItem(self.users, evt.to.id);
                var objFrom = fromParent ? fromParent.Children : self.users;
                objFrom.splice(objFrom.indexOf(itemSelected), 1);

                if (toParent.Id === itemSelected.Id) {
                    itemSelected.ParentId = null;
                    self.users.push(itemSelected);
                }
                else {
                    itemSelected.ParentId = toParent.Id;
                    toParent.Children.push(itemSelected);
                }
                self.saveUser(itemSelected);
                //   self.active = [];
                return false;
            },
            fetchUsers: function () {
                //load from api
            },
            saveUser: function (user) {
                //save 
            },

        },
        computed: {
            selected() {
                if (!this.active.length) return undefined
                return this.active[0];
            },
        }
    })

Hope I help you. IngD.

like image 86
ingd Avatar answered Oct 28 '25 05:10

ingd