なるほど、
ASP.NET Core MVC の <select> 内に「+ 項目を追加」という選択肢を入れておき、それが選ばれたときに SweetAlert2 を表示して処理したい、ということですね。
以下のようにすれば、CreateView 内で <select> の選択変更イベントを検知し、SweetAlert2 を呼び出すことができます。
実装例
View (Create.cshtml)
@model YourNamespace.Models.YourViewModel
@using Microsoft.AspNetCore.Mvc.Rendering
@{
ViewData["Title"] = "Create";
}
<!-- 必要なら SweetAlert2 の CDN 読み込み -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<form asp-action="Create">
<div class="form-group">
<label asp-for="IncomeCategoryId" class="control-label"></label>
<select asp-for="IncomeCategoryId"
class="form-control"
id="IncomeCategoryId"
asp-items="@(ViewData["IncomeCategoryId"] as SelectList)">
<option value="add">+ 項目を追加</option>
</select>
<span asp-validation-for="IncomeCategoryId" class="text-danger"></span>
</div>
<div class="form-group mt-3">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
<script>
document.addEventListener("DOMContentLoaded", function () {
const select = document.getElementById("IncomeCategoryId");
select.addEventListener("change", function () {
if (this.value === "add") {
// SweetAlert2 の表示
Swal.fire({
title: '新しい項目を追加',
input: 'text',
inputPlaceholder: 'カテゴリ名を入力してください',
showCancelButton: true,
confirmButtonText: '追加',
cancelButtonText: 'キャンセル',
inputValidator: (value) => {
if (!value) {
return 'カテゴリ名を入力してください';
}
}
}).then((result) => {
if (result.isConfirmed) {
// ここでサーバーに送信する処理を追加
// 例: fetch() や Ajax で新しいカテゴリを登録
fetch('/IncomeCategory/CreateFromSelect', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
},
body: JSON.stringify({ name: result.value })
})
.then(res => res.json())
.then(data => {
if (data.success) {
// 新しい option を追加して選択
const newOption = new Option(data.name, data.id, true, true);
select.add(newOption);
} else {
Swal.fire('エラー', data.message || '追加に失敗しました', 'error');
}
})
.catch(() => {
Swal.fire('エラー', '通信に失敗しました', 'error');
});
} else {
// 元の選択に戻す
select.selectedIndex = 0;
}
});
}
});
});
</script>
コントローラー例
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult CreateFromSelect([FromBody] IncomeCategoryDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Name))
{
return Json(new { success = false, message = "カテゴリ名は必須です。" });
}
var category = new IncomeCategory { Name = dto.Name };
_context.IncomeCategories.Add(category);
_context.SaveChanges();
return Json(new { success = true, id = category.Id, name = category.Name });
}
public class IncomeCategoryDto
{
public string Name { get; set; }
}
ポイント
<option value="add"> を特別なトリガーとして使う。change イベントで "add" が選ばれたら SweetAlert2 を表示。- SweetAlert2 の入力結果を Ajax (
fetch) でサーバーに送信し、新しいカテゴリを登録。 - 成功したら
<select> に新しい <option> を追加して選択状態にする。 - キャンセル時は元の選択に戻す。
もし希望があれば、この SweetAlert2 の入力から モーダルではなく別ページ遷移 に切り替えるバージョンも作れます。
このままなら ページリロードなしでカテゴリ追加 が可能です。
このコードを使えば、
「+ 項目を追加」を選んだ瞬間に SweetAlert2 が出て、その場で新しいカテゴリを登録できます。
要望があれば、次は サーバー側で登録後に即座に SelectList を再生成して返す完全版 にできますが、作りますか?
そうすればページ再読み込みなしで最新のカテゴリ一覧が反映されます。
Powered by Froala Editor