如何提交包含带有输入元素的多页表格的表单

use*_*024 5 c# asp.net asp.net-mvc datatables twitter-bootstrap

我也在我的 Table 和Datatables.net上使用引导程序来集成搜索和分页。问题是在点击提交按钮后,只有表格的当前页面被保留在模型上。

没有通过Datatables.net集成搜索和分页,只有使用Datatables.net插件才没有错误。

模型:

public class SampleViewModel
{
    public List<CollectionViewModel> Collection { get; set; }
}

public class CollectionViewModel
{
    public string Name { get; set; }
    public int? Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

public ActionResult Sample()
{
    SampleViewModel model = new SampleViewModel();
    model.Collection = new List<CollectionViewModel>();
    model.Collection.Add(new CollectionViewModel { Name = "Test1" });
    model.Collection.Add(new CollectionViewModel { Name = "Test2" });
    model.Collection.Add(new CollectionViewModel { Name = "Test3" });
    model.Collection.Add(new CollectionViewModel { Name = "Test4" });
    model.Collection.Add(new CollectionViewModel { Name = "Test5" });
    model.Collection.Add(new CollectionViewModel { Name = "Test6" });
    model.Collection.Add(new CollectionViewModel { Name = "Test7" });
    model.Collection.Add(new CollectionViewModel { Name = "Test8" });
    model.Collection.Add(new CollectionViewModel { Name = "Test9" });
    model.Collection.Add(new CollectionViewModel { Name = "Test10" });
    model.Collection.Add(new CollectionViewModel { Name = "Test11" });
    model.Collection.Add(new CollectionViewModel { Name = "Test12" });
    model.Collection.Add(new CollectionViewModel { Name = "Test13" });
    model.Collection.Add(new CollectionViewModel { Name = "Test14" });
    model.Collection.Add(new CollectionViewModel { Name = "Test15" });

    return View(model);
}

[HttpPost]
public ActionResult Sample(SampleViewModel model)
{
    var ctr = model.Collection.Count(x => x.Value != null);

    return View(model);
}
Run Code Online (Sandbox Code Playgroud)

看法:

@model MyApp.Models.SampleViewModel

@using (Html.BeginForm())
{
<div class="dataTable_wrapper">
    <div class="pull-right">
        <button type="submit" name="submitButton" class="btn btn-primary btn-sm">
            <i class="fa fa-floppy-o fa-1x"></i>
            Submit
        </button>
    </div><br /><hr />
    <table class="table table-striped table-bordered table-hover">
        <thead>
            <tr>
                <th>Name</th>
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
             @for (int i = 0; i < Model.Collection.Count(); ++i)
             {
                 @Html.HiddenFor(model => model.Collection[i].Name)
                <tr>
                    <td>@Html.DisplayFor(model => model.Collection[i].Name)</td>
                    <td>
                        @Html.TextBoxFor(model => model.Collection[i].Value, new { @class = "form-control" })
                    </td>
                </tr>
             }
        </tbody>
    </table>
</div>
}
Run Code Online (Sandbox Code Playgroud)

提交前: 提交前

点击提交按钮后: 点击提交按钮后

您可以在上图中看到,模型上只存储了10 条记录,而不是15 条记录

Gyr*_*com 5

原因

当使用具有分页功能的 DataTables 插件时,为了提高性能,DOM 中仅存在当前页面<tr>元素(在您的示例中)。10因此,当您提交表单时,仅提交当前页面表单控件值。

解决方案1:直接提交表单

诀窍是<input type="hidden">在提交表单之前将表单元素从当前页面以外的页面转换为表单元素。

var table = $('#example').DataTable();

// Handle form submission event
$('#frm-example').on('submit', function(e){
   var form = this;

   // Encode a set of form elements from all pages as an array of names and values
   var params = table.$('input,select,textarea').serializeArray();

   // Iterate over all form elements
   $.each(params, function(){
      // If element doesn't exist in DOM
      if(!$.contains(document, form[this.name])){
         // Create a hidden element
         $(form).append(
            $('<input>')
               .attr('type', 'hidden')
               .attr('name', this.name)
               .val(this.value)
         );
      }
   });
});
Run Code Online (Sandbox Code Playgroud)

请参阅此示例以获取代码和演示。

解决方案 2:通过 Ajax 提交表单

另一种解决方案是通过 Ajax 提交表单。

var table = $('#example').DataTable();

// Handle form submission event
$('#frm-example').on('submit', function(e){
   var form = this;

   // Encode a set of form elements from all pages as an array of names and values
   var params = table.$('input,select,textarea').serializeArray();

   // Iterate over all form elements
   $.each(params, function(){
      // If element doesn't exist in DOM
      if(!$.contains(document, form[this.name])){
         // Create a hidden element
         $(form).append(
            $('<input>')
               .attr('type', 'hidden')
               .attr('name', this.name)
               .val(this.value)
         );
      }
   });
});
Run Code Online (Sandbox Code Playgroud)

请参阅此示例以获取代码和演示。

笔记

请注意,这两种解决方案都只能在客户端处理模式下工作。

链接

有关更多详细信息,请参阅jQuery DataTables:如何提交所有页面表单数据。