記事詳細


投稿日
2026年09月26日18時45分
タイトル

ASP.NET Core MVC: CreateViewのform内の<select asp-for="SubjectNameId" class="form-control" asp-items="@(ViewData["SubjectNameId"] as SelectList)">のリストの「“+項目を追加”」を選択したらSweetAlert2 を使用した AJAX + モーダル内フォーム にしてページ遷移せずに項目追加 → 再読み込みする方法を教えてください。ControllerのCreateアクションメソッド内には、ViewData["SubjectNameId"] = new SelectList(_context.SubjectNames, "SubjectNameId", "CourseName", payment.SubjectNameId);があります。SubjectNameクラスは、public int SubjectNameId, string CurseName, string ImageUrl があり、アイコンImageファイルをPC内から選択し、プロジェクトのwwwroot/Images フォルダ内に追加し、同時にデータベースSubjectNamesにも追加登録します。

内容

わかりました。
あなたのケースでは、ASP.NET Core MVC の <select> に「+項目を追加」を入れておき、選択されたら SweetAlert2 のモーダルフォームを表示 → AJAX で新しい項目を追加 → 成功後に <select> のリストを再読み込みする、という流れになります。

以下に 完全な実装例 を示します。
ポイントは以下です:

  1. Controller に新規項目追加用の AddSubjectName アクションを作る(AJAX用)。
  2. SweetAlert2 モーダル内でフォームを作り、画像ファイルも送信できるように FormData を使う。
  3. 成功後に再度 SubjectNameId のリストを取得して <select> を更新する(ページ遷移なし)。
  4. 画像は wwwroot/Images に保存し、DB にも登録。

1. View(Create.cshtml)

Cshtml
@model YourNamespace.Models.Payment <form asp-action="Create" method="post" enctype="multipart/form-data"> <div class="form-group"> <label asp-for="SubjectNameId"></label> <select asp-for="SubjectNameId" class="form-control" asp-items="@(ViewData["SubjectNameId"] as SelectList)" id="SubjectNameId"> </select> </div> <button type="submit" class="btn btn-primary">登録</button> </form> @section Scripts { <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> document.getElementById('SubjectNameId').addEventListener('change', function () { if (this.value === 'add') { // 「+項目を追加」が選択された場合 Swal.fire({ title: '新しい科目を追加', html: ` <input id="courseName" class="swal2-input" placeholder="科目名"> <input type="file" id="imageFile" class="swal2-file"> `, focusConfirm: false, showCancelButton: true, confirmButtonText: '追加', preConfirm: () => { const courseName = document.getElementById('courseName').value; const imageFile = document.getElementById('imageFile').files[0]; if (!courseName) { Swal.showValidationMessage('科目名を入力してください'); return false; } const formData = new FormData(); formData.append('CourseName', courseName); if (imageFile) formData.append('ImageFile', imageFile); return fetch('/SubjectNames/AddSubjectName', { method: 'POST', body: formData }) .then(response => { if (!response.ok) throw new Error(response.statusText); return response.json(); }) .catch(error => { Swal.showValidationMessage(`リクエスト失敗: ${error}`); }); } }).then((result) => { if (result.isConfirmed) { Swal.fire('追加成功', '', 'success'); reloadSubjectList(result.value.id); } }); } }); function reloadSubjectList(selectedId) { fetch('/SubjectNames/GetSubjectList') .then(res => res.json()) .then(data => { const select = document.getElementById('SubjectNameId'); select.innerHTML = ''; data.forEach(item => { const opt = document.createElement('option'); opt.value = item.subjectNameId; opt.textContent = item.courseName; select.appendChild(opt); }); // 「+項目を追加」も再追加 const addOpt = document.createElement('option'); addOpt.value = 'add'; addOpt.textContent = '+項目を追加'; select.appendChild(addOpt); // 新しく追加した項目を選択状態に select.value = selectedId; }); } </script> }

2. Controller(SubjectNamesController)

Csharp
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using YourNamespace.Data; using YourNamespace.Models; using System.IO; using System.Threading.Tasks; public class SubjectNamesController : Controller { private readonly ApplicationDbContext _context; private readonly IWebHostEnvironment _env; public SubjectNamesController(ApplicationDbContext context, IWebHostEnvironment env) { _context = context; _env = env; } [HttpPost] public async Task<IActionResult> AddSubjectName([FromForm] string CourseName, [FromForm] IFormFile ImageFile) { if (string.IsNullOrWhiteSpace(CourseName)) return BadRequest("CourseName is required"); string imagePath = null; if (ImageFile != null && ImageFile.Length > 0) { var fileName = Path.GetFileName(ImageFile.FileName); var savePath = Path.Combine(_env.WebRootPath, "Images", fileName); using (var stream = new FileStream(savePath, FileMode.Create)) { await ImageFile.CopyToAsync(stream); } imagePath = "/Images/" + fileName; } var subject = new SubjectName { CourseName = CourseName, ImageUrl = imagePath }; _context.SubjectNames.Add(subject); await _context.SaveChangesAsync(); return Json(new { id = subject.SubjectNameId }); } [HttpGet] public async Task<IActionResult> GetSubjectList() { var list = await _context.SubjectNames .Select(s => new { subjectNameId = s.SubjectNameId, courseName = s.CourseName }) .ToListAsync(); return Json(list); } }

3. Createアクション(PaymentController)

Csharp
public IActionResult Create() { var subjects = _context.SubjectNames.ToList(); subjects.Add(new SubjectName { SubjectNameId = 0, CourseName = "+項目を追加" }); ViewData["SubjectNameId"] = new SelectList(subjects, "SubjectNameId", "CourseName"); return View(); }

実装の流れ

  1. 初期表示
    <select> に既存科目 + 「+項目を追加」を表示。
  2. 「+項目を追加」選択時
    SweetAlert2 モーダルフォームを表示。
  3. AJAX送信
    AddSubjectName に FormData で送信(画像含む)。
  4. 成功後
    GetSubjectList で最新リストを取得し <select> を更新。
  5. ページ遷移なし
    新しい項目が即座に選択状態になる。

💡 この方法なら、ページ遷移せずに項目追加が可能で、画像もアップロードできます。
もし希望があれば、SweetAlert2 のモーダル内にプレビュー表示やバリデーション強化も追加できます。

次に、必要ならこのコードを 部分ビュー化して再利用 できる形に

Powered by Froala Editor

添付画像

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