1

I have a Kendo TreeView bound to a DataSource that is connected to a CRUD API via its transport object.

I now want to re-order nodes in the tree using drag and drop and save these changes to the DB.

I do this by calling .sync() on the DataSource in the dragend event handler of the treeview.

var commandsTreeview = $("#commandgroups-treeview").kendoTreeView({
    dataSource: myDataSource,
    dragAndDrop: true,
    dragend: function(e) {
        // sync changes to the db
        myDataSource.sync();
}

});

However this will create two ajax calls:

  1. PUT with all updates
  2. DELETEon the node that has been dragged and dropped.

In the API I could react on all changes in the PUT request and re-organize my object relations in tha database but then the object gets deleted afterwards.

This is really bad as in the database there is a bunch of other tables that have foreign keys on that object and get deleted on cascade, as well.

This is confusing me.

  1. Why would a dragged object be deleted?
  2. How can I prevent this from happening?

Edit: here's my workaround

  1. Gather the information I need for my service
  2. Calling my service manually
  3. Remember what nodes are expanded
  4. Cancel the changes that kendo stored in the datasource
  5. Re-read the data from the service (the data has been manupulated by the drag and drop service call earlier, so it reflects the new order already)
  6. Re-expand all remembered nodes, as the read call will close all tree nodes

Some code

//…         
dragend: function(e) {

    var dragAndDropData = {};
    dragAndDropData.dropPosition = e.dropPosition;
    dragAndDropData.sourceNode = JSON.parse(kendo.stringify(myDataSource.getByUid($(e.sourceNode).attr('data-uid'))));
    dragAndDropData.destinationNode = JSON.parse(kendo.stringify(myDataSource.getByUid($(e.destinationNode).attr('data-uid'))));

    $.ajax({
        url: myServiceUrl,
        type: 'get',
        dataType: 'html',
        contentType: "application/json",
        data: dragAndDropData
    })
    .done(function(data) {
        // remember expanded nodes
        var expandedItemsIds = [];
        commandsTreeview.element.find(".k-item").each(function (index, value) {
            var item = commandsTreeview.dataItem(this);
            if (item.expanded) {
                expandedItemsIds.push( item.id );
            }
        });

        // cancel everything the kendo widget has done wrong
        // e.g. wrong indexes or items marked to delete
        myDataSource.cancelChanges();

        // re-read the (correct) data from the server
        var promise = myDataSource.read();

        // reset expanded nodes
        promise.done(function() {
            $(expandedItemsIds).each(function(index, value) {
                var nodeToExpand = commandsTreeview.findByUid(myDataSource.get(value).uid);
                commandsTreeview.expand(nodeToExpand);
            });
        });

    })

}
vollstock
  • 126
  • 1
  • 9
  • Hi, did you find how to deal with this? – anon Dec 23 '15 at 13:39
  • Well no and yes. Basically I hacked around it by implementing the dragend function like in the above example. Only did not call sync on the datasource but handled the data myself and cancelled all changes that kendo did on the datasource. I will update the post so I can give you some source code. – vollstock Jan 13 '16 at 09:37

0 Answers0