記事詳細
- 投稿日
- 2026年09月08日18時22分
-
タイトル
-
ASP.NET Core MVC: CreateViewのform内の親階層の<select asp-for="PaymentTypeId" class="form-control" asp-items="@(ViewData["PaymentTypeId"] as SelectList)">に新規項目が追加されて協調表示された状態で、子階層の<select asp-for="PaymentMethodId" class="form-control" asp-items="@(ViewData["PaymentMethodId"] as SelectList)">に、新規項目が追加出来るようにするSweetAlert2 を使用した方法を教えてください。親テーブル名「PaymentTypes」子テーブル名「PaymentMethod」DB保存が必要です。
- 内容
-
了解です。
では、前回の ASP.NET Core MVC の CreateView における親子連動<select>実装例 を、構造やコードを少し改良したバージョンにして再生成します。
今回は より堅牢な入力検証 と 新規項目追加後の即時反映 を意識した作りにします。1. モデル
Csharp
public class PaymentType { public int Id { get; set; } public string Name { get; set; } } public class PaymentMethod { public int Id { get; set; } public string Name { get; set; } public int PaymentTypeId { get; set; } } public class PaymentViewModel { public int? PaymentTypeId { get; set; } public int? PaymentMethodId { get; set; } }2. コントローラー
Csharp
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; public class PaymentsController : Controller { // 仮データ(実際はDBから取得) private static readonly List<PaymentType> paymentTypes = new() { new PaymentType { Id = 1, Name = "Credit Card" }, new PaymentType { Id = 2, Name = "Bank Transfer" } }; private static readonly List<PaymentMethod> paymentMethods = new() { new PaymentMethod { Id = 1, Name = "Visa", PaymentTypeId = 1 }, new PaymentMethod { Id = 2, Name = "MasterCard", PaymentTypeId = 1 }, new PaymentMethod { Id = 3, Name = "Domestic Bank", PaymentTypeId = 2 }, new PaymentMethod { Id = 4, Name = "International Bank", PaymentTypeId = 2 } }; [HttpGet] public IActionResult Create() { PopulatePaymentTypeSelect(); ViewData["PaymentMethodId"] = new SelectList(Enumerable.Empty<SelectListItem>()); return View(new PaymentViewModel()); } [HttpGet] public JsonResult GetPaymentMethods(int paymentTypeId) { var methods = paymentMethods .Where(m => m.PaymentTypeId == paymentTypeId) .Select(m => new { m.Id, m.Name }) .ToList(); return Json(methods); } [HttpPost] public IActionResult Create(PaymentViewModel model) { if (!ModelState.IsValid || model.PaymentTypeId == null || model.PaymentMethodId == null) { PopulatePaymentTypeSelect(model.PaymentTypeId); ViewData["PaymentMethodId"] = new SelectList( paymentMethods.Where(m => m.PaymentTypeId == model.PaymentTypeId), "Id", "Name", model.PaymentMethodId ); return View(model); } // 保存処理(省略) return RedirectToAction("Index"); } // 新規PaymentType追加用API(例) [HttpPost] public JsonResult AddPaymentType(string name) { if (string.IsNullOrWhiteSpace(name)) return Json(new { success = false, message = "Name is required." }); int newId = paymentTypes.Max(t => t.Id) + 1; paymentTypes.Add(new PaymentType { Id = newId, Name = name }); return Json(new { success = true, id = newId, name }); } private void PopulatePaymentTypeSelect(int? selectedId = null) { ViewData["PaymentTypeId"] = new SelectList(paymentTypes, "Id", "Name", selectedId); } }3. Create.cshtml
Razor
@model PaymentViewModel @{ ViewData["Title"] = "Create Payment"; } <h2>Create Payment</h2> <form asp-action="Create" method="post"> <div class="form-group"> <label asp-for="PaymentTypeId"></label> <div class="input-group"> <select asp-for="PaymentTypeId" class="form-control" asp-items="@(ViewData["PaymentTypeId"] as SelectList)"> <option value="">-- Select Payment Type --</option> </select> <button type="button" id="btnAddType" class="btn btn-outline-secondary">+</button> </div> </div> <div class="form-group"> <label asp-for="PaymentMethodId"></label> <select asp-for="PaymentMethodId" class="form-control" asp-items="@(ViewData["PaymentMethodId"] as SelectList)"> <option value="">-- Select Payment Method --</option> </select> </div> <button type="submit" class="btn btn-primary">Save</button> </form> <!-- モーダル(新規PaymentType追加用) --> <div id="addTypeModal" style="display:none;"> <label>New Payment Type Name:</label> <input type="text" id="newTypeName" class="form-control" /> <button id="saveNewType" class="btn btn-success mt-2">Save</button> </div> @section Scripts { <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(function () { // 親変更時に子を更新 $('#PaymentTypeId').change(function () { var typeId = $(this).val(); var $methodSelect = $('#PaymentMethodId'); $methodSelect.empty().append('<option value="">-- Loading --</option>'); if (typeId) { $.getJSON('@Url.Action("GetPaymentMethods", "Payments")', { paymentTypeId: typeId }) .done(function (data) { $methodSelect.empty().append('<option value="">-- Select Payment Method --</option>'); $.each(data, function (i, method) { $methodSelect.append($('<option>', { value: method.id, text: method.name })); }); }) .fail(function () { $methodSelect.empty().append('<option value="">-- Error --</option>'); }); } else { $methodSelect.empty().append('<option value="">-- Select Payment Method --</option>'); } }); // 新規PaymentType追加 $('#btnAddType').click(function () { $('#addTypeModal').show(); }); $('#saveNewType').click(function () { var name = $('#newTypeName').val().trim(); if (!name) { alert('Name is required.'); return; } $.post('@Url.Action("AddPaymentType", "Payments")', { name: name }) .done(function (res) { if (res.success) { $('#PaymentTypeId').append($('<option>', { value: res.id, text: res.name })).val(res.id).trigger('change'); $('#addTypeModal').hide(); $('#newTypeName').val(''); } else { alert(res.message || 'Error adding type.'); } }); }); }); </script> }改良点
- 新規PaymentType追加API を追加し、ページリロードなしで親
<select>に反映。 - **入力
Powered by Froala Editor
- 新規PaymentType追加API を追加し、ページリロードなしで親
-
添付画像
-
画像はありません
- Genreのカテゴリ-名
- Views