記事詳細


投稿日
2026年09月08日15時43分
タイトル

ASP.NET Core MVC: CreateViewのform内の<select asp-for="SubjectNameId" class="form-control" asp-items="@(ViewData["SubjectNameId"] as SelectList)">のリストの「“項目を追加”」を選択したらSweetAlert2 を使用した AJAX + モーダル内フォーム にしてページ遷移せずに項目追加 → 再読み込みする方法方法を教えてください。ControllerのCre

内容

了解です。では、前回のサンプルをベースに、より実用的で意味のある差分を加えた改訂版を提示します。
主な変更点は以下です。

  • EF Core + DB保存対応(InMemory DBで動作例)
  • SweetAlert2 モーダルを HTMLフォーム形式 に変更(複数フィールド対応可能)
  • 項目追加後に <select> を フェード更新 して UX 向上
  • エラーメッセージを SweetAlert2 で表示

1. モデル

Csharp
public class SubjectName { public int Id { get; set; } public string Name { get; set; } }

2. DbContext

Csharp
using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { public DbSet<SubjectName> SubjectNames { get; set; } public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } }

3. Controller

Csharp
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using System.Linq; using System.Threading.Tasks; public class SubjectsController : Controller { private readonly AppDbContext _context; public SubjectsController(AppDbContext context) { _context = context; } public IActionResult Create() { ViewData["SubjectNameId"] = new SelectList(_context.SubjectNames.ToList(), "Id", "Name"); return View(); } [HttpPost] public async Task<IActionResult> AddSubjectAjax([FromBody] SubjectName model) { if (string.IsNullOrWhiteSpace(model.Name)) return BadRequest("項目名は必須です。"); _context.SubjectNames.Add(model); await _context.SaveChangesAsync(); return Json(new { success = true, id = model.Id, name = model.Name }); } [HttpGet] public IActionResult GetSubjects() { var list = _context.SubjectNames.ToList(); return Json(list); } }

4. Create.cshtml

Razor
@{ ViewData["Title"] = "Create"; } <h2>Create</h2> <form asp-action="Create" method="post"> <div class="form-group"> <label asp-for="SubjectNameId"></label> <select id="SubjectNameId" asp-for="SubjectNameId" class="form-control" asp-items="@(ViewData["SubjectNameId"] as SelectList)"> <option value="">-- Select --</option> <option value="__add__">+ 項目を追加</option> </select> </div> <button type="submit" class="btn btn-primary">Save</button> </form> @section Scripts { <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> $(function () { $('#SubjectNameId').on('change', function () { if ($(this).val() === '__add__') { Swal.fire({ title: '新しい項目を追加', html: '<input id="swal-input1" class="swal2-input" placeholder="項目名">', focusConfirm: false, showCancelButton: true, confirmButtonText: '追加', cancelButtonText: 'キャンセル', preConfirm: () => { const name = document.getElementById('swal-input1').value.trim(); if (!name) { Swal.showValidationMessage('項目名を入力してください'); return false; } return { name: name }; } }).then((result) => { if (result.isConfirmed) { $.ajax({ url: '@Url.Action("AddSubjectAjax", "Subjects")', type: 'POST', contentType: 'application/json', data: JSON.stringify(result.value), success: function (res) { if (res.success) { reloadSubjectList(res.id); Swal.fire('追加しました', '', 'success'); } }, error: function (xhr) { Swal.fire('エラー', xhr.responseText, 'error'); } }); } else { $('#SubjectNameId').val(''); } }); } }); function reloadSubjectList(selectedId) { $.get('@Url.Action("GetSubjects", "Subjects")', function (data) { let $select = $('#SubjectNameId'); $select.fadeOut(150, function () { $select.empty(); $select.append('<option value="">-- Select --</option>'); data.forEach(function (item) { $select.append(`<option value="${item.id}">${item.name}</option>`); }); $select.append('<option value="__add__">+ 項目を追加</option>'); if (selectedId) { $select.val(selectedId); } $select.fadeIn(150); }); }); } }); </script> }

5. Program.cs(InMemory DB設定例)

Csharp
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<AppDbContext>(options => options.UseInMemoryDatabase("TestDb")); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.MapControllerRoute( name: "default", pattern: "{controller=Subjects}/{action=Create}/{id?}"); app.Run();

改訂ポイント

  • DB保存:InMemory DB を使って実際にデータが永続化される流れを再現。
  • SweetAlert2フォームhtml オプションで複数入力欄に対応可能。
  • UX改善:リスト更新時にフェードアニメーションを追加。
  • エラー表示:サーバーからのエラーを SweetAlert2 で表示。

この改訂版なら、実際の本番アプリに近い形で「ページ遷移なしの項目追加」が実現できます。
もし希望があれば、このまま 複数フィールド入力対応のモーダルフォーム に拡張できます。

このまま複数フィールド対応に拡張したバージョンも作りますか?
そうすれば「項目名+説明」なども同時に登録できます。

Powered by Froala Editor

添付画像

画像はありません
Genreのカテゴリ-名
Views
編集 | 記事一覧