public class Basket
{
public int Id { get; set; }
public string Sharp { get; set; }
public string Material { get; set; }
public List<Fruit> Fruits { get; set; }
}
public class Fruit
{
public int Id { get; set; }
public string Color { get; set; }
public string Taste { get; set; }
}
With the above example, how could I create both Basket and Fruit in the same asp-form without using any JavaScript?
<form method="post" asp-controller="Basket" asp-action="Create">
<input asp-for="Material" />
<input asp-for="Sharp" />
@*I would like to also create custom amounts of new Fruit in this form.*@
<input type="submit" value="Submit" />
</form>
If my razor form is defined as the above example, how could I create custom amounts of Fruit and create Basket at the same form? It is possible to avoid using JavaScript in this case?
CodePudding user response:
It is possible to avoid using JavaScript in this case?
Based on your scenario and current architecture what you need to do is, there should be a table
where you would be adding your fruit object
as it's a List<Fruit> Fruit
kind of. As per your given code, your output should be as below:
how could I create custom amounts of Fruit and create Basket at the same form?
You could follow the below steps to achieve what you are trying to implement.
View:
@model DotNet6MVCWebApp.Models.Basket
<form method="post" asp-controller="Yonny" asp-action="Create">
<div >
<label asp-for="Material" ></label>
<input asp-for="Material" />
<span asp-validation-for="Material" ></span>
</div>
<div style="padding-bottom:20px">
<label asp-for="Sharp" ></label>
<input asp-for="Sharp" />
<span asp-validation-for="Sharp" ></span>
</div>
@*I would like to also create custom amounts of new Fruit in this form.*@
<div style="padding-bottom:20px">
<button type="button" onclick="AddRow()">Add Fruit</button>
</div>
<div id="dataTable">
<table>
<thead>
<tr>
<th>Id</th>
<th>Color</th>
<th>Taste</th>
</tr>
</thead>
<tbody id="FruitList" data-count="0">
</tbody>
</table>
</div>
<input type="submit" value="Submit" />
</form>
@section Scripts {
<script>
/*
. Hidding table on load
*/
document.getElementById('dataTable').style.display ='none';
function AddRow()
{
var countVal = parseInt($('#FruitList').attr('data-count'));
var html = '';
html = '<tr>';
html = '<td><input type="text" name="Fruits[' countVal '].Id" /></td>';
html = '<td><input type="text" name="Fruits[' countVal '].Color" /></td>';
html = '<td><input type="text" name="Fruits[' countVal '].Taste" /></td>';
html = '</tr>';
$('#FruitList').append(html);
countVal = 1;
$('#FruitList').attr('data-count', countVal);
/*
. Showing table when adding item into
*/
document.getElementById('dataTable').style.display ='block';
}
</script>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(
[Bind("Id,Material,Sharp,Fruits")] DotNet6MVCWebApp.Models.Basket basket)
{
if (ModelState.IsValid)
{
//Save Basket
_context.Add(basket);
await _context.SaveChangesAsync();
//Add Fruits List
foreach (var item in basket.Fruits)
{
_context.Add(item);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Create));
}
return View(basket);
}
Note:
If you somehow got null data while sending request to controller
make sure your binding property
that is Bind("Id,Material,Sharp,Fruits")
are same as name="Fruits[' countVal '].Id"
inside the javascript function
Output: