Я пытаюсь создать форму, которая будет динамически создавать входные данные только для чтения с использованием javascript и передавать эти значения вместе со значениями модели в контроллер, но мой FormCollection в моем методе контроллера содержит только значения модели, а не входные значения. Любая помощь в том, что я делаю неправильно, была бы потрясающей. Вот мой код:
Model.Courses содержит тип CourseId и строку CourseName. Я создаю входные данные только для чтения со значением CourseName для передачи в FormCollection, чтобы установить порядок курсов, содержащихся в каждом учебном лагере.
Вид:
<div class = "container">
<div class = "row">
<div class = "col-xs-12">
<h2>Create Bootcamp</h2>
@using (Html.BeginForm("Create", "LMSBootcamp", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class = "form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class = "form-group">
@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class = "col-md-10">
@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class = "row">
<div class = "col-xs-6 w-50">
<h5>Course Order</h5>
<ol id = "orderContainer">
</ol>
</div>
<div class = "col-xs-6 w-50">
<h5>Available Courses</h5>
<ul>
@foreach (var course in Model.Courses.OrderBy(a=>a.CourseName))
{
<li id = "@course.CourseId" onclick = "Add_Course()" data-arg = "@course.CourseId">@course.CourseName</li>
}
</ul>
</div>
</div>
<div class = "form-group">
<div class = "col-md-offset-2 col-md-10">
<input type = "submit" value = "Create" class = "btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
<script type = "text/javascript">
function Add_Course() {
var courseName = event.target.innerHTML;
var courseId = event.target.getAttribute('data-arg');
//create the readonly input for the course desired
var order = document.createElement("input");
order.readOnly = true;
order.setAttribute("type", "text");
order.setAttribute("value", courseName);
order.classList.add("form-control", "text-box", "single-line");
//create li element
var listElement = document.createElement("li");
listElement.onclick = function Remove_Course() {
var element = event.target
element.remove();
}
//add input to list element
listElement.appendChild(order);
//add list element to container
var orderContainer = document.getElementById("orderContainer");
orderContainer.appendChild(listElement);
}
Контроллер:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(FormCollection courseOrder)
{
return RedirectToAction("Index");
}
Спасибо!
Перед отправкой убедитесь, что эти динамически добавленные входные данные имеют правильные имена моделей, и все будет в порядке. Итак, в вашем примере это будет что-то похожее на это:
<input type = "text" name = "courseName[0]" value = "courseName 1"/>
<input type = "text" name = "courseName[1]" value = "courseName 2"/>
<input type = "text" name = "courseName[3]" value = "courseName 3"/>
И связыватель модели автоматически создаст список строк с этими 3 строками ("courseName 1", "courseName 2", "courseName 3") и назначит его соответствующему свойству, в данном случае значение.
Вот демо:
Модели:
public class FormModel {
public string Title { get; set; }
public List<Course> Courses { get; set; }
}
public class Course {
public int CourseId { get; set; }
public string CourseName { get; set; }
}
Просмотр (перед отправкой формы добавьте имя к каждому добавленному вводу):
@model FormModel
<div class = "row">
<div class = "col-xs-12">
<h2>Create Bootcamp</h2>
@using (Html.BeginForm("Create", "LMSBootcamp", FormMethod.Post, new { id = "myForm" }))
{
@Html.AntiForgeryToken()
<div class = "form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class = "form-group">
@Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
<div class = "col-md-10">
@Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
</div>
</div>
<div class = "row">
<div class = "col-xs-6 w-50">
<h5>Course Order</h5>
<ol id = "orderContainer">
</ol>
</div>
<div class = "col-xs-6 w-50">
<h5>Available Courses</h5>
<ul>
@foreach (var course in Model.Courses.OrderBy(a => a.CourseName))
{
<li id = "@course.CourseId" onclick = "Add_Course()" data-arg = "@course.CourseId">@course.CourseName</li>
}
</ul>
</div>
</div>
<div class = "form-group">
<div class = "col-md-offset-2 col-md-10">
<input type = "submit" value = "Create" class = "btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</div>
</div>
@section scripts{
<script type = "text/javascript">
function Add_Course() {
var courseName = event.target.innerHTML;
var courseId = event.target.getAttribute('data-arg');
//create the readonly input for the course desired
var order = document.createElement("input");
order.readOnly = true;
order.setAttribute("type", "text");
order.setAttribute("value", courseName);
order.classList.add("form-control", "text-box", "single-line");
//create li element
var listElement = document.createElement("li");
listElement.onclick = function Remove_Course() {
var element = event.target
element.remove();
}
//add input to list element
listElement.appendChild(order);
//add list element to container
var orderContainer = document.getElementById("orderContainer");
orderContainer.appendChild(listElement);
}
//add name before form submit
$('#myForm').submit(function () {
var i = 0;
$("#orderContainer li").each(function () {
$(this).find("input").attr("name", "courseName[" + i+"]");
i++;
})
// DO STUFF...
return true; // return false to cancel form action
});
</script>
}
Контроллер:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(FormCollection courseOrder)
{
return Ok();
}
результат:
Ваши динамически создаваемые элементы ввода нуждаются в атрибуте
name
.