Kendo UI grid drag&drop stops working after adding

2019-09-11 06:30发布

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();

Fiddle.

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?

1条回答
三岁会撩人
2楼-- · 2019-09-11 07:32

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:

cancel: function() {
    window.setTimeout(function() {
        createDraggable();
    }, 1); 
},
save: function() {
    window.setTimeout(function() {
        createDraggable();
    }, 1); 
}

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 have remove and edit events as well.

Fiddle

查看更多
登录 后发表回答