我正在使用 ASP.NET MVC 构建每月预算应用程序,我希望允许用户同时创建多个收入条目(大屏幕上最多 5 个表单,小屏幕上最多 3 个表单)。
目前,我正在使用一个包含收入表单列表的 ViewModel,但我正在努力在视图中动态添加或删除表单。理想情况下,用户应该能够单击“+”按钮添加新的收入表格或单击“x”按钮删除表格。
// GET: Incomes/Create
public IActionResult Create()
{
var model = new MultipleIncomeVM();
ViewData["BudgetId"] = new SelectList(_context.Budgets, "BudgetId", "Name");
ViewData["CategoryId"] = new SelectList(_context.Categories, "CategoryId", "Name");
return View(model);
}
// POST: Incomes/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(MultipleIncomeVM incomevm)
{
try
{
// Validate only the incomes with Amount greater than 0
var validIncomes = incomevm.Incomes.Where(i => i.Amount > 0);
if (ModelState.IsValid)
{
foreach (var i in validIncomes)
{
// Add each income
_context.Add(i);
await _context.SaveChangesAsync();
// A new transaction
var transaction = new Transaction
{
Date = i.DateReceived,
Type = ControllersName.GetControllerName(this.GetType().Name),
Detail = i.Source,
Amount = i.Amount,
BudgetId = i.BudgetId,
CategoryId = i.CategoryId
};
_context.Add(transaction);
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
ViewData["BudgetId"] = new SelectList(_context.Budgets, "BudgetId", "Name");
ViewData["CategoryId"] = new SelectList(_context.Categories, "CategoryId", "Name");
return View(incomevm);
}
namespace My_Budget.ViewModels
{
public class MultipleIncomeVM
{
public List<Income> Incomes { get; set; } = new List<Income>
{
new Income { DateReceived = DateTime.Today }
};
}
}
@model My_Budget.ViewModels.MultipleIncomeVM
@{
ViewData["Title"] = "Create Incomes";
}
<h1>Create Multiple Incomes</h1>
<hr />
<div class="row">
<div class="col-md-12">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<table class="table table-bordered">
<thead>
<tr>
<th>Source</th>
<th>Amount</th>
<th>Date Received</th>
<th>Category</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Incomes.Count; i++)
{
<tr>
<td>
<input asp-for="@Model.Incomes[i].Source" class="form-control" />
<span asp-validation-for="@Model.Incomes[i].Source" class="text-danger"></span>
</td>
<td>
<input asp-for="@Model.Incomes[i].Amount" class="form-control" />
<span asp-validation-for="@Model.Incomes[i].Amount" class="text-danger"></span>
</td>
<td>
<input asp-for="@Model.Incomes[i].DateReceived" class="form-control" type="date" />
<span asp-validation-for="@Model.Incomes[i].DateReceived" class="text-danger"></span>
</td>
<td>
<select asp-for="@Model.Incomes[i].CategoryId" class="form-control" asp-items="ViewBag.CategoryId"></select>
<span asp-validation-for="@Model.Incomes[i].CategoryId" class="text-danger"></span>
</td>
<td>
<i class="bi bi-plus-circle" id="add-form"></i>
<i class="bi bi-x-circle" disabled></i>
</td>
<td>
@* Hidden value *@
<select asp-for="@Model.Incomes[i].BudgetId" hidden class="form-control" asp-items="ViewBag.BudgetId" ></select>
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
到目前为止我尝试过的:
I've created a list in the ViewModel to hold multiple income entries.
I can display multiple forms initially, but I'm unsure how to handle dynamic addition/removal of forms in the view.
我的目标是在视图中管理收入表单的创建和删除(也许使用JS?),以便用户可以根据需要交互式地添加或删除表单。
谢谢!
要在 ASP.NET MVC 应用程序中启用动态添加和删除收入表单,您可以使用 JavaScript(或 jQuery)来操作 DOM。
@model My_Budget.ViewModels.MultipleIncomeVM
@{
ViewData["Title"] = "Create Incomes";
}
<h1>Create Multiple Incomes</h1>
<hr />
<div class="row">
<div class="col-md-12">
<form asp-action="Create" id="incomeForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<table class="table table-bordered" id="incomeTable">
<thead>
<tr>
<th>Source</th>
<th>Amount</th>
<th>Date Received</th>
<th>Category</th>
<th></th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Incomes.Count; i++)
{
<tr>
<td>
<input asp-for="@Model.Incomes[i].Source" class="form-control" />
<span asp-validation-for="@Model.Incomes[i].Source" class="text-danger"></span>
</td>
<td>
<input asp-for="@Model.Incomes[i].Amount" class="form-control" />
<span asp-validation-for="@Model.Incomes[i].Amount" class="text-danger"></span>
</td>
<td>
<input asp-for="@Model.Incomes[i].DateReceived" class="form-control" type="date" />
<span asp-validation-for="@Model.Incomes[i].DateReceived" class="text-danger"></span>
</td>
<td>
<select asp-for="@Model.Incomes[i].CategoryId" class="form-control" asp-items="ViewBag.CategoryId"></select>
<span asp-validation-for="@Model.Incomes[i].CategoryId" class="text-danger"></span>
</td>
<td>
<button type="button" class="btn btn-danger remove-form">Remove</button>
</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-success" id="add-form">Add Income</button>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
<script>
$(document).ready(function () {
var maxForms = 5; // Maximum forms allowed
var formCount = $('#incomeTable tbody tr').length;
// Add form button click event
$('#add-form').click(function () {
if (formCount < maxForms) {
var newRow = `<tr>
<td>
<input name="Incomes[${formCount}].Source" class="form-control" />
</td>
<td>
<input name="Incomes[${formCount}].Amount" class="form-control" />
</td>
<td>
<input name="Incomes[${formCount}].DateReceived" class="form-control" type="date" />
</td>
<td>
<select name="Incomes[${formCount}].CategoryId" class="form-control" asp-items="ViewBag.CategoryId"></select>
</td>
<td>
<button type="button" class="btn btn-danger remove-form">Remove</button>
</td>
</tr>`;
$('#incomeTable tbody').append(newRow);
formCount++;
} else {
alert('Maximum of 5 income entries allowed.');
}
});
// Remove form button click event
$(document).on('click', '.remove-form', function () {
$(this).closest('tr').remove();
formCount--;
});
});
</script>
}