I am junior (or less than junior) in IT. I have a problem with passing data from view to controller... What I want to achieve: When user click:
<button type="submit" class="btn btn-primary">Dodaj kategorię</button>
I want pass whole object "Category" to controller (also with List Subcategory). Second button with id="addSubCategory" will add a field to enter the next subcategory, but I want to send everything after clicking the type = submit button. How can I pass all subcategories name to list and send one post method?
That is my View:
@model AplikacjaFryzjer_v2.Models.Category @{ ViewData["Title"] = "Dodaj nową kategorię"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h1>Dodaj nową kategorię</h1> <form method="post"> <div class="row"> <div class="col-md-6"> <div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <button type="submit" class="btn btn-primary">Dodaj kategorię</button> </div> <div class="col-md-6 offset-6"> <div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Subcategories"></label> <input asp-for="Subcategories" /> <span asp-validation-for="Subcategories" class="text-danger"></span> </div> <button class="btn btn-primary" id="addSubCategory" value="table">Dodaj podkategorię</button> </div> </div> </form>
My Action CreateCategory in controller:
[HttpPost]
public IActionResult CreateCategory(Category category)
{
_categoriesRepository.AddCategory(category);
return RedirectToAction("ManageCategories");
}
And my object (model):
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public List<Subcategory> Subcategories {get;set;}
}
For submitting complex models, you need to ensure that the name attribute of these controls bound to the Subcategory class fields are displayed in the form of a collection index .
And trigger the addSubCategory
click event in js to add Subcategory control and data.
Since you added model validation, I suggest you use ViewBag.Subcategories
to save the Subcategories data that has been added to the current page to prevent data loss after clicking the validation .
And you only need to add an asp-validation-summary in your form. Since these fields belong to a model and are in a form, their error information will be counted in the asp-validation-summary div.
Here is a complete example:
public class Category
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public List<Subcategory> Subcategories { get; set; }
}
public class Subcategory
{
[Required]
[DisplayName("Subcategory.Name")]
public string Name { get; set; }
}
Controller:
public IActionResult CreateCategory()
{
ViewBag.Subcategories = new List<Subcategory>() { };
return View();
}
[HttpPost]
public IActionResult CreateCategory(Category category)
{
if (!ModelState.IsValid)
{
// store Subcategories data which has been added
ViewBag.Subcategories = category.Subcategories == null ? new List<Subcategory>() { } : category.Subcategories;
return View("CreateCategory");
}
_categoriesRepository.AddCategory(category);
return RedirectToAction("ManageCategories");
}
View:
@model AplikacjaFryzjer_v2.Models.Category
@{
ViewData["Title"] = "Dodaj nową kategorię";
Layout = "~/Views/Shared/_Layout.cshtml";
var SubcategoriesData = (IList<AplikacjaFryzjer_v2.Models.Subcategory>)ViewBag.Subcategories;
}
<h1>Dodaj nową kategorię</h1>
<form method="post">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Dodaj kategorię</button>
</div>
<div class="col-md-6 offset-6">
@for (int i = 0; i < SubcategoriesData.Count(); i++)
{
<div class="form-group">
<label>Name@(i)</label>
<input asp-for="Subcategories[i].Name" value="@SubcategoriesData[i].Name" />
<span asp-validation-for="Subcategories[i].Name" class="text-danger"></span>
</div>
}
<button class="btn btn-primary" onclick="RemoveSubcategory(this)" id="removeSubcategory">remove</button>
<button class="btn btn-primary" id="addSubCategory" value="table">Dodaj podkategorię</button>
</div>
<div asp-validation-summary="All" class="text-danger"></div>
</div>
</form>
@section Scripts
{
<script>
var i = @SubcategoriesData.Count()-1;
$(document).ready(function () {
if (@SubcategoriesData.Count() <= 0) {
$("#removeSubcategory").hide();
}
$("#addSubCategory").click(function (e) {
e.preventDefault();
i++;
var name = '<label>Name' + i + '</label><input name = "Subcategories[' + i + '].Name" type="text"/>';
$("#removeSubcategory").before('<div class="form-group">' + name + '</div>');
$("#removeSubcategory").show();
});
});
function RemoveSubcategory(btn) {
event.preventDefault();
$(btn).prev("div").remove();
i--;
if (i == @SubcategoriesData.Count() -1) {
$("#removeSubcategory").hide();
}
}
</script>
}
Here is test result:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.