Опубликовать данные сетки Кендо при отправке формы

Я хочу отправить данные из грида Kendo на сервер и сохранить его в базе данных.

Для этого я использовал форму следующим образом:

@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>
}

Но после отправки данных внутри сетки Kendo не отображается. Как я могу опубликовать данные Grid Kendo на сервере?

Ответ 1

Данные сетки не находятся в элементах формы. Элементы формы появляются только при редактировании ячейки, затем ее удаляют. Вы не можете отправлять данные на сервер с помощью кнопки отправки формы.

Правильным способом для этого было бы добавление команды "save", которую предоставляет сетка:

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

Или, позвонив saveChanges() в виджет Grid:

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

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

Ответ 2

Сетка не является элементом формы и не может быть просто отправлена ​​на сервер. Вы можете использовать шаблоны, которые предоставляет Grid, и создавать скрытые элементы на основе различных моделей строк, которые должны быть отправлены на сервер.

Тот же подход используется в этой библиотеке кода, которая демонстрирует именно то, что вы ищете.

Ответ 3

Предположим, что у меня на моей странице три сетки кендо и два текстовых поля. Теперь я хочу опубликовать все данные вместе с данными трех сетей. Я сделал это ниже стиля.

@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
        )
    {
}