I have a form which asks users for their personal info and their family members.
fields of the family members section is repeating.
my question is what is best practice to handle these kind of repeating forms?
I currently use AJAX to repeat forms but how to collect data from these repeating fields?
我有一个表格,询问用户的个人信息和他们的家庭成员。家庭成员部分的领域正在重复。我的问题是处理这些重复形式的最佳做法是什么?我目前使用AJAX重复表单,但如何从这些重复字段中收集数据?
since some one asked for how I repeat form, I do it like this: AJAX Call
因为有人询问我如何重复形式,我这样做:AJAX Call
$(document).on('click', '.btn-add-item', function (e) {
e.preventDefault();
var $results = $('#results');
$.ajax({
url: '/AJAX/AddFamilyForm',
type: 'post',
success: function (data) {
$(data).appendTo($results);
afterAJAX();
}
});
});
C# code
C#代码
[HttpPost]
public PartialViewResult AddFamilyForm()
{
if (!Request.IsAjaxRequest()) return null;
return PartialView("_FamilyForm");
}
3 个解决方案
#1
15
This is some skeleton code on how to get this to work with proper model-binding in MVC. You'll need to write some JS to be able to delete/add new rows.
这是一些关于如何在MVC中使用正确的模型绑定来实现此功能的框架代码。您需要编写一些JS才能删除/添加新行。
Model
模型
public class MyModel
{
public FamilyMembers[] FamilyMembers { get; set; }
}
View
视图
<button id="addNewFamilyMember" type="button">Add</button>
@if (Model.FamilyMembers != null)
{
for (int i = 0; i < Model.FamilyMembers.Length; i++)
{
<tr>
<td>
<button type="button">Delete</button>
@Html.Hidden("FamilyMembers.Index", i)
</td>
<td>
@Html.TextBoxFor(m => Model.FamilyMembers[i].Relation)
</td>
<td>
@Html.TextBoxFor(m => Model.FamilyMembers[i].FullName)
</td>
</tr>
}
}
Below is the code for adding a new member. It creates html dynamically and is able to bind to the posted model because of naming conventions. time
gives each added row a unique id so all the data stays together.
以下是添加新成员的代码。它动态创建html,并且由于命名约定,它能够绑定到发布的模型。 time为每个添加的行提供唯一的ID,以便所有数据保持在一起。
JS (using Jquery)
JS(使用Jquery)
var hidden = '@Html.Hidden("FamilyMembers.Index", "{id}")';
var relationHtml = '@Html.TextBox("FamilyMembers[{id}].Relation")';
var fullNameHtml = '@Html.TextBox("FamilyMembers[{id}].FullName")';
$("#addNewFamilyMember").on("click", function () {
var time = Date.now();
var deleteHtml = "<button type='button'>Delete</button>";
$("#familyMembers-table").find("tbody")
.append($("<tr><td>" + hidden.replace("{id}", time) + deleteHtml + "</td>" +
"<td>" + relationHtml.replace("{id}", time) + "</td>" +
"<td>" + fullNameHtml.replace("{id}", time) + "</td></tr>"));
});
#2
1
One of the solution could be combination of hidden field and control name.
其中一个解决方案可能是隐藏字段和控件名称的组合。
Steps:
脚步:
- Use a hidden field to keep the count the number of row.
- 使用隐藏字段将计数保持为行数。
- Create controls with name like text_relation_1 for first row and text_relation_2 for second row and so on
- 创建控件,其名称类似于第一行的text_relation_1,第二行的text_relation_2,依此类推
- Generate other controls in same way.
- 以相同的方式生成其他控件。
- Increase and decrease the hidden field value so that when values post you can know the number of rows added by the user
- 增加和减少隐藏字段值,以便在发布值时可以知道用户添加的行数
On your action use FormCollection
and loop though hidden field number and get the values from FormCollection
在您的操作上使用FormCollection并循环隐藏字段编号并从FormCollection获取值
Like suppose I created 3 rows then I can create a action like below
就像假设我创建了3行,然后我可以创建一个如下所示的动作
public ActionResult SomeActionMethod(FormCollection formCollection, string hid)
{
for(int i=1;i<hid;i++)
{
var relationId="text_relation_"+i;
var firstrealtion=formCollection[relationId];
...
}
}
#3
0
You don't need any extra Ajax requests for this, since you can use established and standard <form>
features.
您不需要任何额外的Ajax请求,因为您可以使用已建立的标准
Just append []
to the name of the added forms and you'll end up with an array rather than a single value in your HTTP request once the form is submitted:
只需将[]添加到添加的表单的名称中,一旦提交表单,您将在HTTP请求中以数组而不是单个值结束:
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
In this example you'd end up with an array relation
and an array fullname
, both containing your datasets.
在这个例子中,你最终会得到一个数组关系和一个数组fullname,它们都包含你的数据集。
#1
15
This is some skeleton code on how to get this to work with proper model-binding in MVC. You'll need to write some JS to be able to delete/add new rows.
这是一些关于如何在MVC中使用正确的模型绑定来实现此功能的框架代码。您需要编写一些JS才能删除/添加新行。
Model
模型
public class MyModel
{
public FamilyMembers[] FamilyMembers { get; set; }
}
View
视图
<button id="addNewFamilyMember" type="button">Add</button>
@if (Model.FamilyMembers != null)
{
for (int i = 0; i < Model.FamilyMembers.Length; i++)
{
<tr>
<td>
<button type="button">Delete</button>
@Html.Hidden("FamilyMembers.Index", i)
</td>
<td>
@Html.TextBoxFor(m => Model.FamilyMembers[i].Relation)
</td>
<td>
@Html.TextBoxFor(m => Model.FamilyMembers[i].FullName)
</td>
</tr>
}
}
Below is the code for adding a new member. It creates html dynamically and is able to bind to the posted model because of naming conventions. time
gives each added row a unique id so all the data stays together.
以下是添加新成员的代码。它动态创建html,并且由于命名约定,它能够绑定到发布的模型。 time为每个添加的行提供唯一的ID,以便所有数据保持在一起。
JS (using Jquery)
JS(使用Jquery)
var hidden = '@Html.Hidden("FamilyMembers.Index", "{id}")';
var relationHtml = '@Html.TextBox("FamilyMembers[{id}].Relation")';
var fullNameHtml = '@Html.TextBox("FamilyMembers[{id}].FullName")';
$("#addNewFamilyMember").on("click", function () {
var time = Date.now();
var deleteHtml = "<button type='button'>Delete</button>";
$("#familyMembers-table").find("tbody")
.append($("<tr><td>" + hidden.replace("{id}", time) + deleteHtml + "</td>" +
"<td>" + relationHtml.replace("{id}", time) + "</td>" +
"<td>" + fullNameHtml.replace("{id}", time) + "</td></tr>"));
});
#2
1
One of the solution could be combination of hidden field and control name.
其中一个解决方案可能是隐藏字段和控件名称的组合。
Steps:
脚步:
- Use a hidden field to keep the count the number of row.
- 使用隐藏字段将计数保持为行数。
- Create controls with name like text_relation_1 for first row and text_relation_2 for second row and so on
- 创建控件,其名称类似于第一行的text_relation_1,第二行的text_relation_2,依此类推
- Generate other controls in same way.
- 以相同的方式生成其他控件。
- Increase and decrease the hidden field value so that when values post you can know the number of rows added by the user
- 增加和减少隐藏字段值,以便在发布值时可以知道用户添加的行数
On your action use FormCollection
and loop though hidden field number and get the values from FormCollection
在您的操作上使用FormCollection并循环隐藏字段编号并从FormCollection获取值
Like suppose I created 3 rows then I can create a action like below
就像假设我创建了3行,然后我可以创建一个如下所示的动作
public ActionResult SomeActionMethod(FormCollection formCollection, string hid)
{
for(int i=1;i<hid;i++)
{
var relationId="text_relation_"+i;
var firstrealtion=formCollection[relationId];
...
}
}
#3
0
You don't need any extra Ajax requests for this, since you can use established and standard <form>
features.
您不需要任何额外的Ajax请求,因为您可以使用已建立的标准
Just append []
to the name of the added forms and you'll end up with an array rather than a single value in your HTTP request once the form is submitted:
只需将[]添加到添加的表单的名称中,一旦提交表单,您将在HTTP请求中以数组而不是单个值结束:
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
<input type="text" name="relation[]" /><input type="text" name="fullname[]" />
In this example you'd end up with an array relation
and an array fullname
, both containing your datasets.
在这个例子中,你最终会得到一个数组关系和一个数组fullname,它们都包含你的数据集。