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:
PUT
with all updatesDELETE
on 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.
- Why would a dragged object be deleted?
- How can I prevent this from happening?
Edit: here's my workaround
- Gather the information I need for my service
- Calling my service manually
- Remember what nodes are expanded
- Cancel the changes that kendo stored in the datasource
- 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)
- 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);
});
});
})
}