This is a migrated thread and some comments may be shown as answers.

Limiting Drag and Drop

3 Answers 708 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
AP
Top achievements
Rank 1
Iron
Iron
Veteran
AP asked on 02 Aug 2012, 10:21 AM
I'm migrating an application from the old MVC extensions, to KendoUI.
I finally managed to populate my treeview, and get the ID on selection. I now need to replicate the drag and drop functionality, which limits what items can be dragged where.

Essentially I need to restrict dragging, so that items can only be dragged into items of the level above

i.e. A fourth level item can only be dragged to third level items etc..

In my original application (using the MVC extensions, I did this by using the onNodeDragging event - which I know has been replaced by the Drag event.

The code was:-
function onNodeDragging(e) {
    if (!isDropAllowed(e))
        e.setStatusClass('t-denied');
}
 
function isDropAllowed(e)
 
{
 
    var $dropTarget = $(e.dropTarget);
 
    var hoveredItem = $dropTarget.closest('.t-top,.t-mid,.t-bot');
 
  
 
    if (hoveredItem.length > 0) {
 
        var itemHeight = hoveredItem.outerHeight();
 
        var itemTop = hoveredItem.offset().top;
 
        var itemContent = $dropTarget.closest('.t-in');
 
        var delta = itemHeight / (itemContent.length > 0 ? 4 : 2);
 
  
        var insertOnTop = e.pageY < (itemTop + delta);
 
        var insertOnBottom = (itemTop + itemHeight - delta) < e.pageY;
 
        var addChild = itemContent.length > 0 && !insertOnTop && !insertOnBottom;
 
          
 
        if (addChild)
 
            return $dropTarget.parents('.t-item').length == itemLevel;
 
        else
 
            return $dropTarget.parents('.t-item').length == itemLevel + 1;
 
    }
 
      
 
    return false;
 
}


I've changed the setStatusClass line to
e.setStatusClass("k-denied");

But I'm at a loss on how to alter the isDropAllowed function to work with the KendoTreeView.

Thanks

 

3 Answers, 1 is accepted

Sort by
0
Gianluigi
Top achievements
Rank 1
answered on 09 Aug 2012, 03:23 PM
self.Dragging = function (e) {
 
    if (e.statusClass == 'add') {
        e.setStatusClass("k-denied");
        return;
    }
 
    var source = self.GetNode(e.sourceNode);
    var child = $(e.dropTarget)
            .parents('.k-group')
            .first()
            .children('.k-item')
            .filter(function () {
                return $(this).data('uid') == source.uid
            });
 
    if (child.length == 0) {
        e.setStatusClass("k-denied");
    }
}
 
self.GetNode = function (element) {
    var u = $(element).data('uid');
    if (_.isEmpty(u))
        return undefined;
 
    var treeView = self.tree.data(self.Page.TreeView);
    return treeView.dataSource.getByUid(u);
}

I used something  like that for allowing drag only in the current node 
0
AP
Top achievements
Rank 1
Iron
Iron
Veteran
answered on 22 Aug 2012, 02:05 PM
Thanks for responding - but it's not really what I was after.

I managed to put something together, but only by using the IDs I have assigned each node, and by using them to validate the drop.
    var $dropTarget = $(e.dropTarget);
 
    var hoveredItem = $dropTarget.closest('.k-item');
 
    var treeview = $("#AjaxTreeView").data("kendoTreeView");
 
    var draggedValue=treeview.dataItem(e.sourceNode);
 
    var sourceID=draggedValue.Id;
 
 
    if (!(hoveredItem.length && hoveredItem.parents(".k-treeview").length))
    {
        return false;
    }
    else
    {
        var destination = treeview.dataItem(hoveredItem);
 
    var DestID=destination .Id;
}

The code checks if a node is the drop target, and if it is, gets the ID of the destination node.
0
Robert
Top achievements
Rank 1
answered on 11 Apr 2014, 03:25 PM
I have two treeviews that only have root nodes/items.  I want to be able to drag and drop the parents from one to the other and back, but I don't want the user to be able to nest them at all.  They must always be root.  I also need to be able to re-order them at any point in the tree.

Currently, I can't get it to restrict the addition of nested nodes to the destinationNode.  I've looked at using: the level, item.length, .parentsUntil(".k-treeview", ".k-item").length

Below is the code that I've been playing with.  Does anyone know the combination to prevent the adding child nodes to the destinationNode?

<div id="selectFiles-container">
    <div id="selectFiles-column1">
        Files available for combining:
        @(Html.Kendo().TreeView()
            .Name("optionsTreeView")
            .DragAndDrop(true)
            .DataTextField("Name")
            .DataSource(dataSource => dataSource
                .Read(read => read.Action("NonZipFiles", "Initiate")
                )
            )
            .Events(e => e
                .Select("selectTreeView_select")
                .Drop("onTreeViewDrop")
                .DragEnd("onTreeViewDragEnd")
            )
            .HtmlAttributes(new { style = "height: 400px; width: 300px; border: solid 1px;" })
        )
    </div>
    <div id="selectFiles-column2">
        Ordered Files for combining:
        @(Html.Kendo().TreeView()
            .Name("orderedTreeView")
                    .DragAndDrop(true)
                    .DataTextField("Name")
            .HtmlAttributes(new { style = "height: 400px; width: 300px; border: solid 1px;" })
                            .Events(events => events.Drop("onTreeViewDrop").DragEnd("onTreeViewDragEnd"))
        )
        <br />
        <input type="button" id="btnAppendFiles" onclick="alert('not setup');" value="Combine Files" disabled="disabled" />
    </div>
    <div id="selectFiles-clear"></div>
</div>
<script type="text/javascript">
    var orderedTreeView;
    var optionsTreeView;
    var dstNode;
    var parNode;
 
    $(document).ready(function () {
        optionsTreeView = $("#optionsTreeView").data("kendoTreeView");
        orderedTreeView = $("#orderedTreeView").data("kendoTreeView");
    });
 
    function onTreeViewDrop(e) {
        if (e.valid) {
            e.setValid(false);
            optionsTreeView = $("#optionsTreeView").data("kendoTreeView");
            orderedTreeView = $("#orderedTreeView").data("kendoTreeView");
            dstNode = orderedTreeView.dataItem(e.destinationNode);
 
            var level = $(e.destinationNode).parentsUntil(".k-treeview", ".k-item").length;
            console.log('dstlvl: ' + level);
 
            var destItem = orderedTreeView.dataItem(e.destinationNode);
            console.log('dstItem: ' + destItem);
            if (destItem !== undefined) { console.log('dstItems: ' + destItem.items); }
            if (destItem !== undefined && destItem.items !== undefined) { console.log('dstItems: ' + destItem.items.length); }
 
            if (orderedTreeView.dataItem(e.destinationNode) !== undefined) {
                parNode = orderedTreeView.dataItem(e.destinationNode.parentNode)
                if (dstNode.items !== undefined) {
                    console.log('dstitems: ' + dstNode.items.length);
                }
                if (parNode !== undefined && parNode.items !== undefined) {
                    console.log('dstParitems: ' + parNode.items.length);
                }
            }
            else parNode = undefined;
 
            console.log();
            //if (('selectFiles-column2' === e.destinationNode.parentNode.id || 'selectFiles-column1' === e.destinationNode.parentNode.id)) {
            if ((level === 0 && (destItem === undefined || destItem.items === undefined))
                || (level === 0 && (destItem !== undefined && destItem.items !== undefined && destItem.items.length === 0))) {
                e.setValid(true);
            }
        }
    }
</script>

Tags
TreeView
Asked by
AP
Top achievements
Rank 1
Iron
Iron
Veteran
Answers by
Gianluigi
Top achievements
Rank 1
AP
Top achievements
Rank 1
Iron
Iron
Veteran
Robert
Top achievements
Rank 1
Share this question
or