【问题标题】:How to submit form containing multi-page table with input elements如何提交包含带有输入元素的多页表的表单
【发布时间】:2015-08-30 12:00:40
【问题描述】:

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

没有通过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; }
}

控制器:

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);
}

查看:

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

提交前:

点击提交按钮后:

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

【问题讨论】:

  • 我猜是因为表单上只显示了 10 条记录,所以当您发布时只有它们具有非空值,并且您明确要求 x.Value != null
  • 当使用带有分页的 DataTables 插件时,DOM 中仅存在当前页面 &lt;tr&gt; 元素(在您的示例中为 10)。因此,当您提交表单时,只会提交当前页面表单控件值。
  • 我明白了,所以没有解决方案?也许我不应该使用 Datatables 插件
  • 当然有一个解决方案,但它需要在客户端和服务器端进行额外的编码。

标签: c# asp.net asp.net-mvc twitter-bootstrap datatables


【解决方案1】:

原因

当使用带有分页的 DataTables 插件时,DOM 中仅存在当前页面 &lt;tr&gt; 元素(在您的示例中为 10)以提高性能。因此,当您提交表单时,只会提交当前页面表单控件值。

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

诀窍是在提交表单之前将非当前页面的表单元素转换为&lt;input type="hidden"&gt;

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)
         );
      }
   });
});

有关代码和演示,请参阅this example

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

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

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

// Handle form submission event
$('#frm-example').on('submit', function(e){
   // Prevent actual form submission
   e.preventDefault();

   // Serialize form data
   var data = table.$('input,select,textarea').serialize();

   // Submit form data via Ajax
   $.ajax({
      url: '/echo/jsonp/',
      data: data,
      success: function(data){
         console.log('Server response', data);
      }
   });
});

有关代码和演示,请参阅 this example

注意事项

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

链接

更多详情请见jQuery DataTables: How to submit all pages form data

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2017-02-24
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多