Restrict the drag and drop for particular tree nodes in Vue TreeView component

17 Feb 202524 minutes to read

You can restrict drag and drop operations to allow only dropping files under folders. This can be achieved by using the nodeDragStop and nodeDragging events of the TreeView.

<template>
    <div id="app">
        <div class="control_wrapper">
            <ejs-treeview id='treeview' :fields="fields" :allowDragAndDrop='true' :nodeDragStop='dragStop'
                :nodeDragging='nodeDrag'></ejs-treeview>
        </div>
        <div id="display"></div>
    </div>
</template>

<script setup>

    import { TreeViewComponent as EjsTreeview } from "@syncfusion/ej2-vue-navigations";

    var dataSource = [
        {
            nodeId: '01', nodeText: 'Music', icon: 'folder',
            nodeChild: [
                { nodeId: '01-01', nodeText: 'Gouttes.mp3', icon: 'audio' }
            ]
        },
        {
            nodeId: '02', nodeText: 'Videos', icon: 'folder',
            nodeChild: [
                { nodeId: '02-01', nodeText: 'Naturals.mp4', icon: 'video' },
                { nodeId: '02-02', nodeText: 'Wild.mpeg', icon: 'video' },
            ]
        },
        {
            nodeId: '03', nodeText: 'Documents', icon: 'folder',
            nodeChild: [
                { nodeId: '03-01', nodeText: 'Environment Pollution.docx', icon: 'docx' },
                { nodeId: '03-02', nodeText: 'Global Water, Sanitation, & Hygiene.docx', icon: 'docx' },
                { nodeId: '03-03', nodeText: 'Global Warming.ppt', icon: 'ppt' },
                { nodeId: '03-04', nodeText: 'Social Network.pdf', icon: 'pdf' },
                { nodeId: '03-05', nodeText: 'Youth Empowerment.pdf', icon: 'pdf' },
            ]
        },
        {
            nodeId: '04', nodeText: 'Pictures', icon: 'folder', expanded: true,
            nodeChild: [
                {
                    nodeId: '04-01', nodeText: 'Camera Roll', icon: 'folder', expanded: true,
                    nodeChild: [
                        { nodeId: '04-01-01', nodeText: 'WIN_20160726_094117.JPG', image: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/9.png' },
                        { nodeId: '04-01-02', nodeText: 'WIN_20160726_094118.JPG', image: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/3.png' },
                    ]
                },
                { nodeId: '04-02', nodeText: 'Wind.jpg', icon: 'images' },
                { nodeId: '04-03', nodeText: 'Stone.jpg', icon: 'images' },
            ]
        },
        {
            nodeId: '05', nodeText: 'Downloads', icon: 'folder',
            nodeChild: [
                { nodeId: '05-01', nodeText: 'UI-Guide.pdf', icon: 'pdf' },
                { nodeId: '05-02', nodeText: 'Tutorials.zip', icon: 'zip' },
                { nodeId: '05-03', nodeText: 'Game.exe', icon: 'exe' },
                { nodeId: '05-04', nodeText: 'TypeScript.7z', icon: 'zip' },
            ]
        },
    ];

    const fields = { dataSource: dataSource, id: 'nodeId', text: 'nodeText', child: 'nodeChild', iconCss: 'icon', imageUrl: 'image' };

    const nodeDrag = (args) => {
        if (args.droppedNode != null && args.droppedNode.getElementsByClassName('folder') && args.droppedNode.getElementsByClassName('folder').length === 0) {
            args.dropIndicator = 'e-no-drop';
        }
    };

    const dragStop = (args) => {
        if (args.droppedNode != null && args.droppedNode.getElementsByClassName('folder') && args.droppedNode.getElementsByClassName('folder').length === 0) {
            args.cancel = true;
        }
    };
</script>

<style>
    @import "../node_modules/@syncfusion/ej2-base/styles/material.css";
    @import "../node_modules/@syncfusion/ej2-vue-navigations/styles/material.css";

    .control_wrapper {
        display: block;
        max-width: 400px;
        max-height: 320px;
        margin: auto;
        overflow: auto;
        border: 1px solid #dddddd;
        border-radius: 3px;
    }

    .e-treeview .e-list-img {
        width: 25px;
        height: 25px;
    }

    /* Loading sprite image for TreeView */
    .e-treeview .e-list-icon {
        background-repeat: no-repeat;
        background-image: url(https://ej2.syncfusion.com/demos/src/treeview/images/icons/file_icons.png);
        height: 20px;
    }

    /* Specify the icon positions based upon class name */
    .e-treeview .e-list-icon.folder {
        background-position: -10px -552px;
    }

    .e-treeview .e-list-icon.docx {
        background-position: -10px -20px;
    }

    .e-treeview .e-list-icon.ppt {
        background-position: -10px -48px;
    }

    .e-treeview .e-list-icon.pdf {
        background-position: -10px -104px;
    }

    .e-treeview .e-list-icon.images {
        background-position: -10px -132px;
    }

    .e-treeview .e-list-icon.zip {
        background-position: -10px -188px;
    }

    .e-treeview .e-list-icon.audio {
        background-position: -10px -244px;
    }

    .e-treeview .e-list-icon.video {
        background-position: -10px -272px;
    }

    .e-treeview .e-list-icon.exe {
        background-position: -10px -412px;
    }
</style>
<template>
    <div id="app">
        <div class="control_wrapper">
            <ejs-treeview id='treeview' :fields="fields" :allowDragAndDrop='true' :nodeDragStop='dragStop'
                :nodeDragging='nodeDrag'></ejs-treeview>
        </div>
        <div id="display"></div>
    </div>
</template>

<script>

    import { TreeViewComponent } from "@syncfusion/ej2-vue-navigations";

    export default {
        name: "App",
        components: {
            "ejs-treeview": TreeViewComponent
        },
        data() {
            var dataSource = [
                {
                    nodeId: '01', nodeText: 'Music', icon: 'folder',
                    nodeChild: [
                        { nodeId: '01-01', nodeText: 'Gouttes.mp3', icon: 'audio' }
                    ]
                },
                {
                    nodeId: '02', nodeText: 'Videos', icon: 'folder',
                    nodeChild: [
                        { nodeId: '02-01', nodeText: 'Naturals.mp4', icon: 'video' },
                        { nodeId: '02-02', nodeText: 'Wild.mpeg', icon: 'video' },
                    ]
                },
                {
                    nodeId: '03', nodeText: 'Documents', icon: 'folder',
                    nodeChild: [
                        { nodeId: '03-01', nodeText: 'Environment Pollution.docx', icon: 'docx' },
                        { nodeId: '03-02', nodeText: 'Global Water, Sanitation, & Hygiene.docx', icon: 'docx' },
                        { nodeId: '03-03', nodeText: 'Global Warming.ppt', icon: 'ppt' },
                        { nodeId: '03-04', nodeText: 'Social Network.pdf', icon: 'pdf' },
                        { nodeId: '03-05', nodeText: 'Youth Empowerment.pdf', icon: 'pdf' },
                    ]
                },
                {
                    nodeId: '04', nodeText: 'Pictures', icon: 'folder', expanded: true,
                    nodeChild: [
                        {
                            nodeId: '04-01', nodeText: 'Camera Roll', icon: 'folder', expanded: true,
                            nodeChild: [
                                { nodeId: '04-01-01', nodeText: 'WIN_20160726_094117.JPG', image: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/9.png' },
                                { nodeId: '04-01-02', nodeText: 'WIN_20160726_094118.JPG', image: 'https://ej2.syncfusion.com/demos/src/treeview/images/employees/3.png' },
                            ]
                        },
                        { nodeId: '04-02', nodeText: 'Wind.jpg', icon: 'images' },
                        { nodeId: '04-03', nodeText: 'Stone.jpg', icon: 'images' },
                    ]
                },
                {
                    nodeId: '05', nodeText: 'Downloads', icon: 'folder',
                    nodeChild: [
                        { nodeId: '05-01', nodeText: 'UI-Guide.pdf', icon: 'pdf' },
                        { nodeId: '05-02', nodeText: 'Tutorials.zip', icon: 'zip' },
                        { nodeId: '05-03', nodeText: 'Game.exe', icon: 'exe' },
                        { nodeId: '05-04', nodeText: 'TypeScript.7z', icon: 'zip' },
                    ]
                },
            ];
            return {
                fields: { dataSource: dataSource, id: 'nodeId', text: 'nodeText', child: 'nodeChild', iconCss: 'icon', imageUrl: 'image' },
            }
        },
        methods: {

            nodeDrag: function (args) {
                if (args.droppedNode != null && args.droppedNode.getElementsByClassName('folder') && args.droppedNode.getElementsByClassName('folder').length === 0) {
                    args.dropIndicator = 'e-no-drop';
                }
            },

            dragStop: function (args) {
                if (args.droppedNode != null && args.droppedNode.getElementsByClassName('folder') && args.droppedNode.getElementsByClassName('folder').length === 0) {
                    args.cancel = true;
                }
            }
        }
    }
</script>

<style>
    @import "../node_modules/@syncfusion/ej2-base/styles/material.css";
    @import "../node_modules/@syncfusion/ej2-vue-navigations/styles/material.css";

    .control_wrapper {
        display: block;
        max-width: 400px;
        max-height: 320px;
        margin: auto;
        overflow: auto;
        border: 1px solid #dddddd;
        border-radius: 3px;
    }

    .e-treeview .e-list-img {
        width: 25px;
        height: 25px;
    }

    /* Loading sprite image for TreeView */
    .e-treeview .e-list-icon {
        background-repeat: no-repeat;
        background-image: url(https://ej2.syncfusion.com/demos/src/treeview/images/icons/file_icons.png);
        height: 20px;
    }

    /* Specify the icon positions based upon class name */
    .e-treeview .e-list-icon.folder {
        background-position: -10px -552px;
    }

    .e-treeview .e-list-icon.docx {
        background-position: -10px -20px;
    }

    .e-treeview .e-list-icon.ppt {
        background-position: -10px -48px;
    }

    .e-treeview .e-list-icon.pdf {
        background-position: -10px -104px;
    }

    .e-treeview .e-list-icon.images {
        background-position: -10px -132px;
    }

    .e-treeview .e-list-icon.zip {
        background-position: -10px -188px;
    }

    .e-treeview .e-list-icon.audio {
        background-position: -10px -244px;
    }

    .e-treeview .e-list-icon.video {
        background-position: -10px -272px;
    }

    .e-treeview .e-list-icon.exe {
        background-position: -10px -412px;
    }
</style>