了解です。では、前回のサンプルをベースに、より実用的で意味のある差分を加えた改訂版を提示します。
主な変更点は以下です。
- EF Core + DB保存対応(InMemory DBで動作例)
- SweetAlert2 モーダルを HTMLフォーム形式 に変更(複数フィールド対応可能)
- 項目追加後に
<select> を フェード更新 して UX 向上 - エラーメッセージを SweetAlert2 で表示
1. モデル
public class SubjectName
{
public int Id { get; set; }
public string Name { get; set; }
}
2. DbContext
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public DbSet<SubjectName> SubjectNames { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
}
3. Controller
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
@{
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設定例)
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