Rahul
Rahul

Reputation: 2307

Post the Kendo Grid Data on Form Submit

I want to Post the data from a Kendo Grid to the server, and save it to a database.

For this I have used form like so:

@using (Html.BeginForm("MainDocumentSave","Document"))
{
    <div class="row-fluid">
        <div class="span10">

            @(Html.Kendo().Grid<Invoice.Models.ViewModels.SegmentViewModel>()
                .Name("Segment")
                .TableHtmlAttributes(new { style = "height:20px; " })
                .Columns(columns =>
                {
                    columns.Bound(p => p.AirlineShortName).EditorTemplateName("AirlineEditor").Title("Airline").ClientTemplate("#=AirlineName#").Width(5);
                    columns.Bound(p => p.DepartureDate).Width(9);
                    columns.Bound(p => p.Arrives).EditorTemplateName("ArrivalLocation").Title("Arrival").ClientTemplate("#=Arrives#").Width(5);
                    columns.Bound(p => p.ArrivalDate).Width(7);
                    columns.Bound(p => p.FlightNumber).Width(8);
                })
                .Editable(editable => editable.Mode(GridEditMode.InCell))
                .Navigatable()
                .Sortable()
                .Scrollable(scr => scr.Height(200))
                .Scrollable()
                .DataSource(dataSource => dataSource
                    .Ajax()
                    .Batch(true)
                    .ServerOperation(false)
                    .Events(events => events.Error("error_handler"))
                    .Model(model => model.Id(p => p.AirlineName))
                    .Create("Editing_Create", "Grid")
                    .Read("Segment_Read", "Document")
                    .Update("Editing_Update", "Grid")
                    .Destroy("Editing_Destroy", "Grid")
                )
            )

        </div>
    </div>
    <button type="submit" class="btn btn-primary"> Save Segments</button>
}

But after submitting, the data inside the Kendo Grid is not Posted. How can I Post Kendo Grid Data to the Server?

Upvotes: 12

Views: 17873

Answers (3)

som
som

Reputation: 11

Suppose I have three kendo grids and two textboxs in my page. Now I want to post all data along with data of three grid. I did this by below style.

@model DAL.ViewModel.ProfileViewModel
@{
    ViewBag.Title = "Profile";
    Layout = "~/Views/Shared/_LayoutAfterLogin.cshtml";
}
<h2>Profile</h2>
<div>
    <h4>ApplicationUser</h4>
    <hr />
    <dl class="dl-horizontal"></dl>
    <form id="frmProfile">
        <div>
            <label>Email<span class="mandatory"></span></label>
            @Html.Kendo().TextBoxFor(model => model.Email)
        </div>
        <div>
            <label>UserName<span class="mandatory"></span></label>
            @Html.Kendo().TextBoxFor(model => model.UserName)
        </div>
    </form>
    @(Html.Kendo().Grid<DAL.ViewModel.PhoneViewModel>()
        .Name("PhoneGrid")
        .Columns(columns =>
            {
                columns.Bound(p => p.PhoneID).Groupable(false);
                columns.Bound(p => p.PhoneType).Width(160);
                columns.Bound(p => p.PhoneNumber).Width(120);
                columns.Bound(p => p.IsPrimary).Width(120);
                columns.Command(command => command.Destroy()).Width(90);
            })
            .ToolBar(toolBar =>
                {
                    toolBar.Create();
                    // toolBar.Save();
                })
            .Editable(editable => editable.Mode(GridEditMode.InCell))
            .Pageable()
            .Sortable()
            .Scrollable()
            .HtmlAttributes(new { style = "height:430px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .Batch(true)
                .ServerOperation(false)
                .Events(events => events.Error("error_handler"))
                .Model(model =>
                {
                    model.Id(p => p.PhoneID);
                    model.Field(p => p.PhoneID).Editable(false);
                })
                .PageSize(20)
                .Read(read => read.Action("PhoneList", "Account"))
                    .Create(create => create.Action("AddPhone", "Account"))
                    .Update(update => update.Action("EditPhone", "Account"))
                    .Destroy(destroy => destroy.Action("DeletePhone", "Account"))
                )
            )
        </div>
        <p>
            <button type="button" id="btnSave">Save</button>
            @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
            @Html.ActionLink("Back to List", "Index")
        </p>

        //jquery
        $("#btnSave").on("click", function () {
                sendData();
            });

            function sendData() {
                var grid = $("#PhoneGrid").data("kendoGrid"),
                    parameterMap = grid.dataSource.transport.parameterMap;

                //get the new and the updated records
                var currentData = grid.dataSource.data();
                var updatedRecords = [];
                var newRecords = [];

                for (var i = 0; i < currentData.length; i++) {
                    if (currentData[i].isNew()) {
                        //this record is new
                        newRecords.push(currentData[i].toJSON());
                    } else if (currentData[i].dirty) {
                        updatedRecords.push(currentData[i].toJSON());
                    }
                }

                //this records are deleted
                var deletedRecords = [];
                for (var i = 0; i < grid.dataSource._destroyed.length; i++) {
                    deletedRecords.push(grid.dataSource._destroyed[i].toJSON());
                }

                var serializedData = $("#frmProfile").serializeObject();

                var data = {};
                $.extend(data, parameterMap({ updated: updatedRecords }), parameterMap({ deleted: deletedRecords }), parameterMap({ new: newRecords }));

                var finaldata = {};
                $.extend(finaldata, parameterMap({ phone: data }), parameterMap({ email: data }), parameterMap({ address: data }), parameterMap({ pagedata: serializedData }));
                $.ajax({
                    url: '@Url.Action("UpdateCreateDelete1", "Account")',
                    data: JSON.stringify(finaldata),
                    type: "POST",
                    contentType: 'application/json',
                    dataType: 'json',
                    error: function (e) {
                        alert('error');
                        //Handle the server errors using the approach from the previous example
                    },
                    success: function () {
                        grid.dataSource._destroyed = [];
                        //refresh the grid - optional
                        // grid.dataSource.read();
                    }
                })
            }

            jQuery.fn.serializeObject = function () {
                var arrayData, objectData;
                arrayData = this.serializeArray();
                objectData = {};

                $.each(arrayData, function () {
                    var value;

                    if (this.value != null) {
                        value = this.value;
                    } else {
                        value = '';
                    }

                    if (objectData[this.name] != null) {
                        if (!objectData[this.name].push) {
                            objectData[this.name] = [objectData[this.name]];
                        }

                        objectData[this.name].push(value);
                    } else {
                        objectData[this.name] = value;
                    }
                });

                return objectData;
            };



        //action method
        public ActionResult UpdateCreateDelete1(
            [Bind(Prefix = "phone.updated")]List<PhoneViewModel> updatedPhone,
            [Bind(Prefix = "phone.new")]List<PhoneViewModel> newPhone,
            [Bind(Prefix = "phone.deleted")]List<PhoneViewModel> deletedPhone,
            [Bind(Prefix = "email")]List<PhoneViewModel> emaillist,
            [Bind(Prefix = "address")]List<PhoneViewModel> addresslist,
            [Bind(Prefix = "pagedata")] ProfileViewModel pagedata
        )
    {
}

Upvotes: 1

Petur Subev
Petur Subev

Reputation: 20203

The Grid is not a form element and it cannot be simply posted to the server. You can take advantage of the templates that the Grid provide and create hidden elements based on the different row models which to be submitted to the server.

The same approach is used in this code library which demonstrates exactly what you are searching for.

Upvotes: 7

CodingWithSpike
CodingWithSpike

Reputation: 43718

The grid data isn't in form elements. The form elements appear only when a cell is being edited, then it is removed. You can't post the data to the server by using a form submit button.

The proper way to to this would be by adding the 'save' command button that the grid provides itself:

@(Html.Kendo().Grid<Invoice.Models.ViewModels.SegmentViewModel>()
    .Name("Segment")
    .ToolBar(toolbar => {
        toolbar.Save(); // add save button to grid toolbar
    })
    // ... rest of options ...

Or by calling saveChanges() on the Grid widget:

<button type="button" id="save">Save Segments</button>

$("#save").on("click", function () {
    $("#Segment").data("kendoGrid").saveChanges();
});

Upvotes: 5

Related Questions