Telerik .NET MVC:- Grid Row Drag & Drop with Inline Editing

Sometime we needs drag and drop facility on grid row, to align rows or to set sequence or may be for some other reasons. This functionality can be achieved in Telerk grid in MVC by using following code. (Same functionality can be implemented in with different type of Telerik or Kendo grids with same changes).In addition to that it also shows,
  1. Hide grid column dynamically on row data bound
  1. Hide pager if only one page is available and display it when pages are more than one
  1. Ajax call to update grid data
  1. Save/Edit/delete/update grid record
  1. Validation on save/update records

<script>
    function onRowDataBound(e) {
        //Databound logic if any
        //e.g. Show/Hide row/colunms/pager

        //1. Hide Colunm
        var PlanGrid = $("#Grid").data("kendoGrid");
        PlanGrid.hideColumn("Colunm1");

        //2. Hide pager
        //Show pager if roow count is more than 50
        if (this.dataSource.totalPages() <= 1 && this.dataSource.pageSize() == 50) {
            $('.k-pager-nav').hide();
            $('.k-pager-numbers').hide();
            $('.k-pager-sizes').hide();
        }
        else {            
            //$('.k-grid-pager *').show();
            $('.k-pager-nav').show();
            $('.k-pager-numbers').show();
            $('.k-pager-sizes').show();
        }

    }

    //Hint Handler
    var noHint = $.noop;
    function placeholder(element) {
        return element.clone().addClass("k-state-hover").css("opacity", 0.65);
    }

    function onChange(e) {
        var grid = $("#Grid").data("kendoGrid"),
            skip = grid.dataSource.skip(),
            oldIndex = e.oldIndex + skip,
            newIndex = e.newIndex + skip,
            data = grid.dataSource.data(),
            dataItem = grid.dataSource.getByUid(e.item.data("uid"));

        grid.dataSource.remove(dataItem);
        grid.dataSource.insert(newIndex, dataItem);

        //Ajax Call to save this cahnges to database
        $.ajax({
            type: 'POST',
     //Write Action or SP to change sequence in database accordingly.
            url: '@Url.Action("UpdateActionName""ControllerName")',
            dataType: 'json',
            data: { ID: dataItem.ID, Sequence: newIndex + 1 },
            success: function (IsSuccess) {
                //Reload/Referesh the grid.
                $('#Grid').data('kendoGrid').dataSource.read();
                $("#Grid").data("kendoGrid").refresh();
            },
            error: function (ex) {
                alert("We are facing some problem please try again later");
                //Reset/Reload/Referesh the grid.
                $('#Grid').data('kendoGrid').dataSource.read();
                $("#Grid").data("kendoGrid").refresh();
            }
        });
    }

    function OnSave(e) {
        //Validations on Save or Update
        if (e.model.Sequence <= 0 || e.model.Sequence == null) {
            e.preventDefault();
            alert("Please enter valid sequence number");
            return false;
        }
        else {
            //To check if newly added item having ID similar to other records
            var dataSource = $("#Grid").data("kendoGrid").dataSource;
            var data = dataSource.data();
            var rowCount = data.length;
            var idx = e.container.index();
            for (var i = 0; i < rowCount; i++) {
                if (i != idx) {
                    if (data[i].PlanID == e.model.PlanID) {
                        e.preventDefault();
                        alert("This ID already exist!");
                        return false;
                    }
                }
            }
        }
    }

    function onEdit(e) {
        var GridID = e.sender.element[0].id;
        if (e.model.isNew()) {
            //Remove move class on new ly added row
            //As we do not want to move record which is not yet saved.
            $("#grid tbody").find("tr[data-uid=" + e.model.uid + "]").css({ 'cursor'"default"'HintHandler''', });
            $("#grid tbody").find("tr[data-uid=" + e.model.uid + "]").removeAttr("onChange")
        }
    }

    function onRequestEnd(e) {
        //Reloading grid on end of Delete or Create request.
        if (e.type == "destroy" || e.type == "create") {
            $('#Grid').data('kendoGrid').dataSource.read();
            $("#Grid").data("kendoGrid").refresh();
        }
    }
</script>

<div>
        @*Defining Telerik Grid*@
        @(Html.Kendo().Grid<ModelObject>
            ()
            .Name("Grid")
            //Set Grid Colunms
            .Columns(columns =>
            {
            columns.Bound(b => b.ID).Title("ID");
            columns.Bound(b => b.Colunm1);
            columns.ForeignKey(b => b.Colunm2).Title("Name");
            columns.Bound(c => c.Sequence);
            columns.Command(command =>
            {
            command.Edit().UpdateText("Save").Text("Edit");
            command.Destroy();
            }).Width(25);
            })
            //Create Toolbar if required to add new row.
            .ToolBar(toolbar => toolbar.Create().HtmlAttributes(new { id = "btnAdd" }))
            //Autobind ad per requred
            .AutoBind(true)
            //Pager As requrement
            .Pageable(pageable => pageable
            .Refresh(true)
            .PageSizes(true)
            .ButtonCount(5))
            .Editable(editable => editable.Mode(GridEditMode.InLine))
            //Define grid event
            .Events(events => { events.DataBound("onRowDataBound"); events.Save("OnSave"); events.Edit("onEdit"); })
            .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(50)
            //Grid Datasource Event Defination
            .Read(read => read.Action("GetAction""ControllerName").Data("JSFunctionForData"))
            .Update(update => update.Action("UpdateAction""ControllerName"))
            .Create(update => update.Action("CreateAction""ControllerName"))
            .Destroy(update => update.Action("DeleteAction""ControllerName"))
            .Model(model => { model.Id(p => p.EventPlanID); })
            //To fire event after datasouce action
            .Events(events => events.RequestEnd("onRequestEnd"))
            )
            )

            @*Code for drag & drop will start from here*@
            @(Html.Kendo().Sortable()
            .For("#Grid")
            .Filter("table > tbody > tr:not(.k-grid-edit-row)")
            .Cursor("move")
            .HintHandler("noHint")
            .PlaceholderHandler("placeholder")
            .ContainerSelector("#Grid tbody")
            .Events(events => events.Change("onChange"))
            )

            @*Styling grid to drag*@
            <style>
                .k-grid tbody tr {
                    cursormove;
                }
            </style>
    </div>

Sample Image


Comments

  1. How can we do drag and drop between pages. I mean when we have more than one page in grid i want 3rd page to be at 1st record, how we can achieve that.

    ReplyDelete
    Replies
    1. It's very difficult to have drag and drop between pages, I am not sure it is possible in telerik grid or not, but it’s really challenging one I will try to find solution for this.

      For now I will suggest to remove paging from grid if possible, so that all records will be on one page.

      Delete

Post a Comment