Yagami Light
Yagami Light

Reputation: 1

Kendo Grid: Drag Drop scrolls to top after drop

I implemented drag&drop for a grid like this:

var mainGrid = $("#grid").kendoGrid({
    dataSource: mainDataSource,
    columns: ["id", "name", "phone"],
    scrollable: true,
    editable: true,
    navigatable: true,
    height: 200
}).data("kendoGrid");

mainGrid.table.kendoDropTarget({
    group: "gridGroup",
    drop: function (e) {

        var draggedRows = e.draggable.hint.find("tr");
        e.draggable.hint.hide();
        var dropLocation = $(document.elementFromPoint(e.clientX, e.clientY)),
            dropGridRecord = mainDataSource.getByUid(dropLocation.parent().attr("data-uid"))
            if (dropLocation.is("th")) {
                return;
            }

        var beginningRangePosition = mainDataSource.indexOf(dropGridRecord), //beginning of the range of dropped row(s)
            rangeLimit = mainDataSource.indexOf(mainDataSource.getByUid(draggedRows.first().attr("data-uid"))); //start of the range of where the rows were dragged from


        //if dragging up, get the end of the range instead of the start
        if (rangeLimit > beginningRangePosition) {
            draggedRows.reverse(); //reverse the records so that as they are being placed, they come out in the correct order
        }

        //assign new spot in the main grid to each dragged row
        draggedRows.each(function () {
            var thisUid = $(this).attr("data-uid"),
                itemToMove = mainDataSource.getByUid(thisUid);
            mainDataSource.remove(itemToMove);
            mainDataSource.insert(beginningRangePosition, itemToMove);
        });


        //set the main grid moved rows to be dirty
        draggedRows.each(function () {
            var thisUid = $(this).attr("data-uid");
            mainDataSource.getByUid(thisUid).set("dirty", true);
        });

        //remark things as visibly dirty
        var dirtyItems = $.grep(mainDataSource.view(), function (e) {
            return e.dirty === true;
        });
        for (var a = 0; a < dirtyItems.length; a++) {
            var thisItem = dirtyItems[a];
            mainGrid.tbody.find("tr[data-uid='" + thisItem.get("uid") + "']").find("td:eq(0)").addClass("k-dirty-cell");
            mainGrid.tbody.find("tr[data-uid='" + thisItem.get("uid") + "']").find("td:eq(0)").prepend('<span class="k-dirty"></span>')
        };
    }
});

JS Fiddle: jsfiddle.net/yagamilight1987/R2EyW/

Scroll down to the last record. Drag and drop the last record to the previous position. The drop works but it scrolls to the top of the grid.

Upvotes: 0

Views: 1605

Answers (2)

Lars H&#246;ppner
Lars H&#246;ppner

Reputation: 18402

You're changing the data source which causes the grid to refresh, and the grid will unfortunately not remember its scroll position when you use the navigatable configuration option. You can fix that by remembering the position and restoring it manually:

    // remember scroll position before you start modifying the data source
    var gridContentDiv = $("#grid").find(".k-grid-content").first();
    var scrollTop =  gridContentDiv.scrollTop();

    // ...

    // restore scroll position when your modifications are done ...
    gridContentDiv.scrollTop(scrollTop);

(updated demo)

Upvotes: 0

Jaimin
Jaimin

Reputation: 8020

Your code is perfectly working on my project i think there are some script issue

Script that use

<script src="~/Script/Jquery-1.8.1.min.js" type="text/javascript"></script>
<script src="@Url.Content("~/Script/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Script/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Script/kendo.all.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Script/kendo.aspnetmvc.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Script/kendo.web.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Script/jquery.maskedinput-1.3.min.js")" type="text/javascript"></script>
<link href="~/Content/kendo.common.min.css" rel="stylesheet" type="text/css" />
<link href="~/Content/kendo.default.min.css" rel="stylesheet" type="text/css" />

View

<div id="grid">
</div>

Code

<script type="text/javascript">
    $(document).ready(function () {

        $.fn.reverse = [].reverse; //save a new function from Array.reverse

        var data = [{
            id: 1,
            name: "Michael",
            phone: "897-894-8956"
        }, {
            id: 2,
            name: "George Michael",
            phone: "897-555-5555"
        }, {
            id: 3,
            name: "George Sr.",
            phone: "897-444-4444"
        }, {
            id: 4,
            name: "Gob",
            phone: "897-333-3333"
        }, {
            id: 5,
            name: "Lucille",
            phone: "897-222-2222"
        }, {
            id: 6,
            name: "Tobias",
            phone: "897-111-1111"
        }, {
            id: 7,
            name: "Maeby",
            phone: "897-666-6666"
        }, {
            id: 8,
            name: "Buster",
            phone: "897-777-7777"
        }, {
            id: 9,
            name: "Lindsay",
            phone: "897-888-8888"
        }];

        var dataModel = kendo.data.Model.define({
            id: "id",
            fields: {
                id: {
                    type: "number",
                    editable: false
                },
                name: {
                    type: "string",
                    editable: true
                },
                phone: {
                    type: "string",
                    editable: false
                }
            }
        });

        var mainDataSource = new kendo.data.DataSource({
            schema: {
                model: dataModel
            },
            data: data
        });

        var mainGrid = $("#grid").kendoGrid({
            dataSource: mainDataSource,
            columns: ["id", "name", "phone"],
            scrollable: true,
            editable: true,
            navigatable: true,
            height: 200
        }).data("kendoGrid");

        var selectedClass = 'k-state-selected';
        $(document).on('click', '#grid tbody tr', function (e) {
            if (e.ctrlKey || e.metaKey) {
                $(this).toggleClass(selectedClass);
            } else {
                $(this).addClass(selectedClass).siblings().removeClass(selectedClass);
            }
        });

        mainGrid.table.kendoDraggable({
            filter: "tbody tr",
            group: "gridGroup",
            axis: "y",
            hint: function (item) {
                var helper = $('<div class="k-grid k-widget drag-helper"/>');
                if (!item.hasClass(selectedClass)) {
                    item.addClass(selectedClass).siblings().removeClass(selectedClass);
                }
                var elements = item.parent().children('.' + selectedClass).clone();
                item.data('multidrag', elements).siblings('.' + selectedClass).remove();
                return helper.append(elements);
            }
        });

        mainGrid.table.kendoDropTarget({
            group: "gridGroup",
            drop: function (e) {

                var draggedRows = e.draggable.hint.find("tr");
                e.draggable.hint.hide();
                var dropLocation = $(document.elementFromPoint(e.clientX, e.clientY)),
            dropGridRecord = mainDataSource.getByUid(dropLocation.parent().attr("data-uid"))
                if (dropLocation.is("th")) {
                    return;
                }

                var beginningRangePosition = mainDataSource.indexOf(dropGridRecord), //beginning of the range of dropped row(s)
            rangeLimit = mainDataSource.indexOf(mainDataSource.getByUid(draggedRows.first().attr("data-uid"))); //start of the range of where the rows were dragged from


                //if dragging up, get the end of the range instead of the start
                if (rangeLimit > beginningRangePosition) {
                    draggedRows.reverse(); //reverse the records so that as they are being placed, they come out in the correct order
                }

                //assign new spot in the main grid to each dragged row
                draggedRows.each(function () {
                    var thisUid = $(this).attr("data-uid"),
                itemToMove = mainDataSource.getByUid(thisUid);
                    mainDataSource.remove(itemToMove);
                    mainDataSource.insert(beginningRangePosition, itemToMove);
                });


                //set the main grid moved rows to be dirty
                draggedRows.each(function () {
                    var thisUid = $(this).attr("data-uid");
                    mainDataSource.getByUid(thisUid).set("dirty", true);
                });

                //remark things as visibly dirty
                var dirtyItems = $.grep(mainDataSource.view(), function (e) {
                    return e.dirty === true;
                });
                for (var a = 0; a < dirtyItems.length; a++) {
                    var thisItem = dirtyItems[a];
                    mainGrid.tbody.find("tr[data-uid='" + thisItem.get("uid") + "']").find("td:eq(0)").addClass("k-dirty-cell");
                    mainGrid.tbody.find("tr[data-uid='" + thisItem.get("uid") + "']").find("td:eq(0)").prepend('<span class="k-dirty"></span>')
                };
            }
        });

    });

</script>

Upvotes: 0

Related Questions