jquery - Add textbox dynamically and post it to controller mvc
问题描述
I am new to mvc.for my application I have create collection in view. Lets say I have to display name and address first time. If user clicks copy it should clone the div of name and address. Even I clone it using Jquery it dosent textboxes. And I have to submit all the data back to controller.But it posting only first entry
I have created viewmodel and loop in view to display those in view. As index is 0 initially it is not displaying those text box.
public class Person
{
public string Name { get; set; }
public string Address { get; set; }
}
public class PersonVM
{
public PersonVM()
{
Persons = new List<Person>();
}
public IList<Person> Persons { get; set; }
}
@model MvcApplication5.Models.PersonVM
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<script src="~/Script/JavaScript.js"></script>
<div class="example-1">
@using (Html.BeginForm("Create", "Person", FormMethod.Post, new { @id = "formpost", @class = "main-form" } ))
{
<div class="example-2">
@for (int i = 0; i < Model.Persons.Count(); i++)
{
<p>Example one</p>
<p>Example two</p>
@Html.TextBoxFor(p => p.Persons[i].Name, null, new { @class = "form-control" })
@Html.TextBoxFor(p => p.Persons[i].Address, null, new { @class = "form-control" })
}
<button type="button" class="btn-copy">Copy</button>
</div>
<input type="submit" id="submit" name="Submit" />
}
</div>
<script>
$(function () {
$(".btn-copy").on('click', function () {
var ele = $(this).closest('.example-2').clone(true);
console.log(ele.find('input'));
//var currentIndex = $(ele).split("[")[1][0];
//var newIndex = Number(currentIndex) + 1;
ele.find('input').each(function () {
console.log($(ele));
this.id = this.id.replace('0', '[' + 2 + ']');
this.name = this.name.replace('[0]', '[' + 2 + ']');
//$(ele).attr("name", $(ele).attr("name").replace(currentIndex, newIndex));
});
$(this).closest('.example-2').after(ele);
});
$(".main-form").on("submit", function () {
//You might need to replace the selector here with something better and
//repeat this for the name as well, or modify it to work with the whole div.
//$.each($(".example-2"), function (index, inputContainer) {
// $.each($(inputContainer).children("div").children("input"), function (inputIndex, input) {
// var currentIndex = $(input).attr("name").split("[")[1][0];
// $(input).attr("name", $(input).attr("name").replace(currentIndex, index));
// });
//});
console.log($('.example-2').val);
});
});
</script>
解决方案
编辑:-我更仔细地查看了代码,并重新创建了它。我做了一些小的改动,但现在看起来是这样的。
//My Controller action methods
public IActionResult Index()
{
var emptyModel = new PersonVM() {
Persons = new List<Person>()
};
emptyModel.Persons.Add(new Person());
return View(emptyModel);
}
[HttpPost]
public IActionResult Index(PersonVM people)
{
return View(people);
}
我没有对视图进行任何更改。但我已经把它都包括在这里了
@model PersonVM
<div class="example-1">
@using (Html.BeginForm("Create", "Person", FormMethod.Post, new { @class = "main-form"}))
{
<div class="example-2">
<div>
@for (int i = 0; i < Model.Persons.Count(); i++)
{
<p>Example one</p>
<p>Example two</p>
@Html.TextBoxFor(p => p.Persons[i].Name, null, new { @class = "form-control" })
@Html.TextBoxFor(p => p.Persons[i].Address, null, new { @class = "form-control" })
}
<button type="button" class="btn-copy">Copy</button>
</div>
</div>
<input type="submit" name="Submit" />
}
</div>
<script>
$(function () {
$(".btn-copy").on('click', function () {
var ele = $(this).closest('.example-2').clone(true);
$(this).closest('.example-2').after(ele);
});
$(".main-form").on("submit", function () {
//You might need to replace the selector here with something better and
//repeat this for the name as well, or modify it to work with the whole div.
$.each($(".example-2"), function (index, inputContainer) {
$.each($(inputContainer).children("div").children("input"), function (inputIndex, input) {
var currentIndex = $(input).attr("name").split("[")[1][0];
$(input).attr("name", $(input).attr("name").replace(currentIndex, index));
});
});
});
});
</script>
希望这能解决您的问题。一个问题是每次克隆时都必须清除 Person 名称和字段的值,但这很容易实现。
您会看到这一点,因为正在提交的所有文本框都具有相同的索引,并且当模型绑定发生时,每个新值都会覆盖现有值。你有两种方法可以解决这个问题。在您的点击监听器中分配新的索引,或者等到用户提交表单。以下是代码示例。
示例 - 1:在添加新文本框之前更新索引。
<script>
//This assumes sequential indices.
$(function () {
$(".btn-copy").on('click', function () {
var ele = $(this).closest('.example-2').clone(true);
var currentIndex = $(ele).split("[")[1][0];
var newIndex = Number(currentIndex) + 1;
$(ele).attr("name", $(ele).attr("name").replace(currentIndex, newIndex);
$(this).closest('.example-2').after(ele);
})
});
</script>
示例 - 2:继续当前方法并在提交时应用索引。
<script>
$(function () {
$(".btn-copy").on('click', function () {
var ele = $(this).closest('.example-2').clone(true);
$(this).closest('.example-2').after(ele);
});
$("{selector for form}").on("submit", function() {
//You might need to replace the selector here with something better and
//repeat this for the name as well, or modify it to work with the whole div.
$.each("input[name='Persons[i].Address']", function(index, input){
var currentIndex = $(input).split("[")[1][0];
var newIndex = Number(currentIndex) + 1;
$(input).attr("name", $(input).attr("name").replace(currentIndex, newIndex);
});
});
})
</script>
推荐阅读
- php - 当我进行 Axios POST 时,我得到 419(未知状态)错误 0
- java - 使用测试代码修补 Java 9 模块以处理反射
- laravel - 预期响应代码 354,但得到代码“503”,消息“503 5.5.1 RCPT first. w15sm3670747wrs.80 - gsmtp”
- spring - Spring AsyncTaskExecutor 返回不抛出异常的期货
- javascript - 使用 React 和 Enzyme 测试 Javascript 类属性
- python - 来人解释一下为什么这段代码对我不起作用?
- c# - Moq 通用存储库模式
- c# - ac# 控制台应用程序可以在 Windows 控件上获取反射信息吗?
- c# - 中继器不创建子控件
- android - 带有大 msg.obj 的处理程序可以抛出 TransactionTooLargeException 吗?