Search code examples
javascriptjquerykendo-uikendo-gridkendo-draggable

dataItem(element) returns incorrect item inside of KendoDraggable - KendoUI JQuery


I have a draggable defined on kendo grid rows like:

$(grid.element).kendoDraggable({
    filter: "table > tbody > tr.grid-row.k-master-row",
    group: "grid-items",
    hint: function (element) {
        grid.collapseRow(element);
        element.addClass("k-state-selected");
        var template = kendo.template($("#grid-item-moving-template").html());
        console.log(element);
        var data = grid.dataItem(element);
        console.log(data);
        var hint = $(template(data));
        return hint;
    },
    cursorOffset: { top: 15, left: 30 }
});

I noticed if I start dragging the items, the first one displays correctly but if I drop the first item into a dropzone and I start dragging a second item, the second item's hint template contains the definition of the first item.

That's where the weird part comes, I drilled inside of the definition adding in the hint function 2 console logs, one with the element passed and the other being the actual data returned from the grid fetched with dataItem(). While element is always correct, if I start dragging 1 I get 1, if I start dragging 2 I get 2, the dataItem(element) for both 1 and 2 always returns the row data for row 1 (But this happens only if the first item was already dropped into a dropzone). Any idea why this might be happening? This is a kendo inbuilt function.


Solution

  • I found the issue.

    Whenever the item would be dropped I would call:

    e.draggable.currentTarget.remove(); 
    

    On the Droppable, in order to remove it from the containing grid but since the dataSource for the grid was not refreshed, the items would dissapear from the grid but they would still be contained on the dataSource. Underneath Kendo dataItem() would look for the item based on its array index, since we had 2 items on the grid but 3 items on the dataSource after the drop, that would lead to a index mismatch (since the previous index held by the dataSource was now occupied by a different item).

    Personally, I think telerik should consider indexing it with the guid key, rather than raw array index, this way such issues would not occur.

    I now pass a callback down to the closure containing droparea calling:

        refreshGrid: function () {
            grid.dataSource.read();
            grid.refresh();
        }
    

    And that solved the issue.