如何在ASP.NET MVC中动态添加和删除同一模型的多个表单?

问题描述 投票:0回答:1

我正在使用 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?),以便用户可以根据需要交互式地添加或删除表单。

谢谢!

javascript c# asp.net-mvc model-view-controller
1个回答
0
投票

要在 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>
}
我希望我能够帮助你:)

© www.soinside.com 2019 - 2024. All rights reserved.