如何提交包含带有输入元素的多页表的表单
Posted
技术标签:
【中文标题】如何提交包含带有输入元素的多页表的表单【英文标题】: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 中仅存在当前页面 <tr>
元素(在您的示例中为 10
)。因此,当您提交表单时,只会提交当前页面表单控件值。
我明白了,所以没有解决方案?也许我不应该使用 Datatables 插件
当然有一个解决方案,但它需要在客户端和服务器端进行额外的编码。
【参考方案1】:
原因
当使用带有分页的 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)
);
);
);
有关代码和演示,请参阅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。
【讨论】:
以上是关于如何提交包含带有输入元素的多页表的表单的主要内容,如果未能解决你的问题,请参考以下文章