【问题标题】:Submit form with Kendo MVC Grid and other elements使用 Kendo MVC Grid 和其他元素提交表单
【发布时间】:2023-04-01 00:54:01
【问题描述】:

我正在尝试获取一个包含 Kendo MVC 网格和其他要提交的元素的表单。

  • View 模型包含三个字符串字段和一个IEnumerable 集合。
  • 网格是服务器绑定的。我没有使用网格从列表中添加任何元素或删除任何元素,但网格包含映射到列表项中的布尔列的复选框。

每当我提交此表单时,三个字符串元素都会在 post 方法中返回,但列表始终为空。

这是数据模型:

public class Parent
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
    public string Comments { get; set; }
    public IEnumerable<ChildItems> Children { get; set; }
}

public class ChildItems
{
    public string ChildField1 { get; set; }
    public string ChildField2 { get; set; }
    public boolean Include { get; set; }
}

这是我的观点:

@{
    ViewBag.Title = "Index";
}
@model GridInForm.Models.Parent

@using(Html.BeginForm("Save", "Home"))
{
    <fieldset>
        <legend>Editing Parent</legend>

        @Html.LabelFor(parent => parent.Field1)
        @Html.EditorFor(parent => parent.Field1)

        @Html.LabelFor(parent => parent.Field2)
        @Html.EditorFor(parent => parent.Field2)
        @Html.LabelFor(parent => parent.Comments)
        @Html.EditorFor(parent => parent.Comments)
        @(Html.Kendo().Grid(Model.Children)
            .Name("Children")
            .ToolBar(tools => tools.Create().Text("Add new Children"))
            .Editable(editable => editable.Mode(GridEditMode.PopUp).CreateAt(GridInsertRowPosition.Bottom))
            .Columns(columns =>
            {
                columns.Bound(p => p.ChildField1).ClientTemplate("#= ChildField1 #" + 
                    "<input type='hidden' name='ChildField1[#= index(data)#].ChildField1' value='#= Name #' />"
                );

                columns.Bound(p => p.ChildField2).Hidden().ClientTemplate("#= ChildField1 #" +
                    "<input type='hidden' name='ChildField1[#= index(data)#].ChildField1' value='#= ChildField1 #' />"
                );

                columns.Command(command => 
                {
                    // command.Destroy();
                    command.Edit();
                }).Width(100);
            })
            .DataSource(dataSource => dataSource
                .Server()
                .Create("Create", "Home")
                .Read("Index", "Home")
                .Update("Update", "Home")
                .Model(model => 
                {
                    model.Id(p => p.ChildField1);
                    model.Field(p => p.ChildField1).Editable(false);
                })
                //.ServerOperation(true)
            )
        )
    </fieldset>

    <input type="submit" value="Save" />
}

<script>
    function index(dataItem) {
        alert("bindind");
        var data = $("#Products").data("kendoGrid").dataSource.data();
        return data.indexOf(dataItem);
    }
</script>

当我提交表单时,我将父项返回到视图模型中,但网格中的 IEnumerable 字段始终为空。

这不是这样做的方法吗?如果是,那么完成这样的事情的方法是什么?我在以前的 Telerik 版本上遇到过这个问题,我发现在 Kendo UI 上也是如此。任何方向将不胜感激。这是一个长期存在的问题。

【问题讨论】:

  • 我正在处理的表单遇到同样的问题。任何帮助都将不胜感激。这真是令人沮丧。

标签: asp.net-mvc post user-interface grid kendo-ui


【解决方案1】:

我的项目中完全有这种情况。这是我的网格声明...

@(Html.Kendo().Grid(Model.ChildLines)
    .Name("RequestLinesGrid")
    .Editable(editable => editable.Mode(Kendo.Mvc.UI.GridEditMode.InCell))
         .Columns(columns =>
         {
             columns.Bound(p => p.ItemCode).ClientTemplate("#= ItemCode #" +
               "<input type='hidden' name='MyLines[#= index(data)#].ItemCode' value='#= ItemCode #' />"
             );
             columns.Bound(p => p.Description).ClientTemplate("#= Description #" +
               "<input type='hidden' name='MyLines[#= index(data)#].Description' value='#= Description #' />"
             );
             columns.Bound(p => p.UoM).ClientTemplate("#= UoM #" +
               "<input type='hidden' name='MyLines[#= index(data)#].UoM' value='#= UoM #' />"
             );
             columns.Bound(p => p.QtyCC).ClientTemplate("#= QtyCC #" +
                "<input type='hidden' name='MyLines[#= index(data)#].QtyCC' value='#= QtyCC #' />"
             );
             columns.Bound(p => p.QtyEmployee).ClientTemplate("#= QtyEmployee #" +
                "<input type='hidden' name='MyLines[#= index(data)#].QtyEmployee' value='#= QtyEmployee #' />"
             );
             columns.Bound(p => p.ItemListLineID).Hidden(true).ClientTemplate("#= ItemListLineID #" +
                "<input type='hidden' name='MyLines[#= index(data)#].ItemListLineID' value='#= ItemListLineID #' />"
             );
             columns.Bound(p => p.ItemListCode).Hidden(true).ClientTemplate("#= ItemListCode #" +
                "<input type='hidden' name='MyLines[#= index(data)#].ItemListCode' value='#= ItemListCode #' />"
             );
             columns.Command(command =>
             {
                 command.Destroy();
             }).Width(200);
         })
    .DataSource(dataSource => dataSource.Ajax()
         .Model(m =>
         {
             m.Id(p => p.ItemCode);
             m.Field(p => p.ItemCode).Editable(false);
             m.Field(p => p.Description).Editable(false);
             m.Field(p => p.UoM).Editable(false);
             m.Field(p => p.QtyCC).Editable(true);
             m.Field(p => p.QtyEmployee).Editable(true);
             m.Field(p => p.ItemListLineID).Editable(false);
             m.Field(p => p.ItemListCode).Editable(false);
         })
         .Batch(true)
         .ServerOperation(false)
         // these are dummy action methods that don't really exist.
         .Update("upd", "upd") 
         .Destroy("del", "del")
         .Create("cre", "cre")
    )
    .Navigatable()
)

这里是“索引”函数:

function index(dataItem) {
    var data = $("#RequestLinesGrid").data("kendoGrid").dataSource.data();

    return data.indexOf(dataItem);
}

【讨论】:

  • 嗨,Shawn,您的解决方案将回发网格的所有行,有没有办法将您的声明更改为仅发布更改的行?
  • 不,必须在控制器操作方法中检查更改的行。
  • 您从哪里获得索引?我遇到了错误?
  • @RyanLege 我已将索引功能添加到我的答案中
  • 首先,很棒的答案。这对我帮助很大。其次,对于遇到此答案并想知道“MyLines”是什么的任何人。它是您的父视图模型上的 Collection/Enumerable/List 的名称。对于老手来说,这可能很明显,但我在调试时花了一两分钟才弄清楚。谢谢肖恩!
【解决方案2】:

所以这里是您问题解决方案的一部分。我扩展了 kendo 数据源,因此您可以调用此函数并获取所有更新、删除、创建的项目。只需将其转换为 json 并将其与您的其余表单字段一起发送回。我现在已经开始工作了。以为我会分享。

kendo.data.DataSource.prototype.GetUnsavedData = function () {
    var that = this,
        idx,
        length,
        created = [],
        updated = [],
        destroyed = that._destroyed,
    allRows = [],
        data = that._flatData(that._data);

    for (idx = 0, length = data.length; idx < length; idx++) {
        if (data[idx].isNew()) {
            created.push(data[idx]);
        } else if (data[idx].dirty) {
            updated.push(data[idx]);
        }
    }

    allRows = created.concat(updated).concat(destroyed);
    var allRowsJSON = JSON.stringify(allRows);
    return allRowsJSON;
}

【讨论】:

    【解决方案3】:

    我受到codebeastie 和@user1878526 的启发,产生了以下混合想法 - 只需将网格作为字符串列表返回到控制器保存操作:

    控制器:

    Function Save(ThisForum As myModel, gridData As List(Of String)) As ActionResult
    

    查看:

    $("#myForm").submit(function (event) {
        var grid = $("#myGrid").data("kendoGrid");
        var data = grid.dataSource.view();
        var input;
        for (var i = 0; i < data.length; i++) {
            var s = JSON.stringify(data[i]).replace(/["']/g, "");
            input = $("<input>", { type: 'hidden', name: 'data[' + i + ']', value: s });
            $(this).append($(input));
        }
    })
    

    这可以在控制器中通过Spliting 逗号和冒号相当容易地进行解析。

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多