わかりました。
あなたのケースでは、ASP.NET Core MVC の <select> に「+項目を追加」を入れておき、選択されたら SweetAlert2 のモーダルフォームを表示 → AJAX で新しい項目を追加 → 成功後に <select> のリストを再読み込みする、という流れになります。
以下に 完全な実装例 を示します。
ポイントは以下です:
- Controller に新規項目追加用の
AddSubjectName アクションを作る(AJAX用)。 - SweetAlert2 モーダル内でフォームを作り、画像ファイルも送信できるように
FormData を使う。 - 成功後に再度
SubjectNameId のリストを取得して <select> を更新する(ページ遷移なし)。 - 画像は
wwwroot/Images に保存し、DB にも登録。
1. View(Create.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)
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)
public IActionResult Create()
{
var subjects = _context.SubjectNames.ToList();
subjects.Add(new SubjectName { SubjectNameId = 0, CourseName = "+項目を追加" });
ViewData["SubjectNameId"] = new SelectList(subjects, "SubjectNameId", "CourseName");
return View();
}
実装の流れ
- 初期表示
<select> に既存科目 + 「+項目を追加」を表示。 - 「+項目を追加」選択時
SweetAlert2 モーダルフォームを表示。 - AJAX送信
AddSubjectName に FormData で送信(画像含む)。 - 成功後
GetSubjectList で最新リストを取得し <select> を更新。 - ページ遷移なし
新しい項目が即座に選択状態になる。
💡 この方法なら、ページ遷移せずに項目追加が可能で、画像もアップロードできます。
もし希望があれば、SweetAlert2 のモーダル内にプレビュー表示やバリデーション強化も追加できます。
次に、必要ならこのコードを 部分ビュー化して再利用 できる形に
Powered by Froala Editor