I have Kendo UI grid with drag&drop functionality:
var data = [
{ id: 1, text: "text 1", position: 0 },
{ id: 2, text: "text 2", position: 1 },
{ id: 3, text: "text 3", position: 2 },
{ id: 4, text: "text 4", position: 40 },
{ id: 5, text: "text 5", position: 100 },
{ id: 6, text: "text 6", position: 600 },
{ id: 7, text: "text 7", position: 47000 },
{ id: 8, text: "text 8", position: 99999 },
{ id: 9, text: "text 9", position: 1000000 }];
var dataSource = new kendo.data.DataSource({
data: data,
schema: {
model: {
id: "id",
fields: {
id: { type: "number" },
text: { type: "string" },
position: { type: "number" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
editable : "popup",
columns: ["id", "text", "position"],
toolbar: ["create"]
}).data("kendoGrid");
var createDraggable = function() {
grid.table.find("tbody tr").kendoDraggable({
cursorOffset: {
top: 10,
left: 10
},
group: "gridGroup",
hint: function(e) {
return $('<div class="k-grid k-widget" style="color:red"><table><tbody><tr>' + e.html() + '</tr></tbody></table></div>');
}
});
grid.table.find("tbody tr").kendoDropTarget({
dragenter: function (e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget));
$(e.dropTarget[0]).addClass("highlight-droparea");
// e.dropTarget.addClass("highlight-droparea");
console.log('entering');
},
dragleave: function (e) {
$(e.dropTarget[0]).removeClass("highlight-droparea");
//e.dropTarget.removeClass("highlight-droparea");
console.log('leaving');
},
group: "gridGroup",
drop: function(e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget).data("uid")),
dest = $(e.target);
if (dest.is("th") || dest.is("thead") || dest.is("span") || dest.parent().is("th")) {
return;
}
//in case the grid contains an image
else if (dest.is("img")) {
dest = grid.dataSource.getByUid(dest.parent().parent().data("uid"));
} else {
dest = grid.dataSource.getByUid(dest.parent().data("uid"));
}
//not on same item
if (target.id !== dest.id) {
//reorder the items
var tmp = target.get("position");
target.set("position", dest.get("position"));
dest.set("position", tmp);
//Lets mark the changes as dirty
target.dirty = true;
dest.dirty = true;
grid.dataSource.sort({ field: "position", dir: "asc" });
}
createDraggable();
}
});
};
createDraggable();
Drag&drop stops working if you create new record or hit "Cancel" while creating new row. The same issue I think would appear in all grid CRUD operations.
Any ideas how to fix this?
This problem happens because kendo redraw all the rows(all DOM elements) again on each action, e.g
save
,cancel
, so any event attached to the DOM are lost.All you have to do is to call the
createDraggable()
on these events to recreate all the drag and drop features. Note that this can be bad if you have a large grid.Below are the grid events:
Yep, it is ugly. The purpose of the
setTimeout
is to simulate an after event, since those events are called like before. I mean, they are called before changes on DOM happens, and we need to apply the drag and drop after that, or they will be all lost again. So the timer executes right after the changes are made and we get an after event. You haveremove
andedit
events as well.Fiddle