SkyoceanHome
Home
Privacy
ダウンロード
SkyShop
Updated Information
チュートリアルコード集
References
記事編集
日付
ジャンルのカテゴリ―名
名前を選択して下さい。
Contexts
Controllers
Databases
Htmls
JavaScripts
Models
MVCTutorials
Others
Styles
Views
タイトル
内容の要旨
<p data-pasted="true">以下は、前回のサンプルを改良した <strong>ASP.NET Core MVC + SweetAlert2 + AJAX</strong> 実装例です。<br>主な変更点は以下です。</p><ul><li><strong>コード構造の整理</strong>(<code>[ValidateAntiForgeryToken]</code> の追加、エラーハンドリング強化)</li><li><strong>SelectList 更新処理の改善</strong>(既存項目重複チェック)</li><li><strong>SweetAlert2 の UX 改善</strong>(入力バリデーション、ローディング表示)</li><li><strong>子セレクトの動的ロード API</strong> を追加(親変更時に自動更新)</li></ul><hr><h2>1. モデル</h2><pre data-priority="2"><div data-bm="28"><h5>Csharp</h5></div><code>// Models/PaymentType.cs public class PaymentType { public int Id { get; set; } public string Name { get; set; } = string.Empty; public ICollection<PaymentMethod> PaymentMethods { get; set; } = new List<PaymentMethod>(); } // Models/PaymentMethod.cs public class PaymentMethod { public int Id { get; set; } public string Name { get; set; } = string.Empty; public int PaymentTypeId { get; set; } public PaymentType? PaymentType { get; set; } } </code></pre><hr><h2>2. コントローラ</h2><pre data-priority="2"><div data-bm="29"><h5>Csharp</h5></div><code>// Controllers/PaymentsController.cs using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; public class PaymentsController : Controller { private readonly AppDbContext _context; public PaymentsController(AppDbContext context) { _context = context; } public IActionResult Create() { ViewData["PaymentTypeId"] = new SelectList(_context.PaymentTypes.AsNoTracking(), "Id", "Name"); ViewData["PaymentMethodId"] = new SelectList(Enumerable.Empty<SelectListItem>()); return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create(Payment payment) { if (ModelState.IsValid) { _context.Add(payment); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(payment); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> AddPaymentType([FromBody] PaymentType model) { if (string.IsNullOrWhiteSpace(model.Name)) return BadRequest("Name is required"); if (await _context.PaymentTypes.AnyAsync(x => x.Name == model.Name)) return Conflict("既に存在します"); _context.PaymentTypes.Add(model); await _context.SaveChangesAsync(); return Json(new { id = model.Id, name = model.Name }); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> AddPaymentMethod([FromBody] PaymentMethod model) { if (string.IsNullOrWhiteSpace(model.Name) || model.PaymentTypeId <= 0) return BadRequest("Invalid data"); if (await _context.PaymentMethods.AnyAsync(x => x.Name == model.Name && x.PaymentTypeId == model.PaymentTypeId)) return Conflict("既に存在します"); _context.PaymentMethods.Add(model); await _context.SaveChangesAsync(); return Json(new { id = model.Id, name = model.Name }); } [HttpGet] public async Task<IActionResult> GetPaymentMethodsByTypeId(int typeId) { var methods = await _context.PaymentMethods .Where(m => m.PaymentTypeId == typeId) .Select(m => new { id = m.Id, name = m.Name }) .ToListAsync(); return Json(methods); } } </code></pre><hr><h2>3. Create.cshtml</h2><pre data-priority="2"><div data-bm="30"><h5>Razor</h5></div><code>@model Payment <div class="form-group"> <label asp-for="PaymentTypeId"></label> <select asp-for="PaymentTypeId" id="PaymentTypeId" class="form-control" asp-items="@(ViewData["PaymentTypeId"] as SelectList)"> <option value="">-- 選択 --</option> </select> <button type="button" id="btnAddPaymentType" class="btn btn-sm btn-primary mt-1">+ 新規追加</button> </div> <div class="form-group"> <label asp-for="PaymentMethodId"></label> <select asp-for="PaymentMethodId" id="PaymentMethodId" class="form-control" asp-items="@(ViewData["PaymentMethodId"] as SelectList)"> <option value="">-- 選択 --</option> </select> <button type="button" id="btnAddPaymentMethod" class="btn btn-sm btn-primary mt-1">+ 新規追加</button> </div> @section Scripts { <script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script> <script> const token = '@Antiforgery.GetTokens(HttpContext).RequestToken'; // 親変更時に子をロード document.getElementById("PaymentTypeId").addEventListener("change", function () { let typeId = this.value; let methodSelect = document.getElementById("PaymentMethodId"); methodSelect.innerHTML = '<option value="">-- 選択 --</option>'; if (!typeId) return; fetch(`@Url.Action("GetPaymentMethodsByTypeId")?typeId=${typeId}`) .then(res => res.json()) .then(data => { data.forEach(m => { methodSelect.add(new Option(m.name, m.id)); }); }); }); // PaymentType 追加 document.getElementById("btnAddPaymentType").addEventListener("click", function () { Swal.fire({ title: '新しい支払タイプ', input: 'text', inputPlaceholder: 'タイプ名を入力', inputValidator: value => !value && '必須項目です', showCancelButton: true, confirmButtonText: '追加' }).then((result) => { if (result.isConfirmed) { Swal.showLoading(); fetch('@Url.Action("AddPaymentType")', { method: 'POST', headers: { 'Content-Type': 'application/json', 'RequestVerificationToken': token }, body: JSON.stringify({ name: result.value }) }) .then(res => { if (res.status === 409) throw new Error("既に存在します"); return res.json(); }) .then(data => { let select = document.getElementById("PaymentTypeId"); if (![...select.options].some(o => o.value == data.id)) { select.add(new Option(data.name, data.id, true, true)); } Swal.fire('追加しました', '', 'success'); }) .catch(err => Swal.fire('エラー', err.message, 'error')); } }); }); // PaymentMethod 追加 document.getElementById("btnAddPaymentMethod").addEventListener("click", function () { let paymentTypeId = document.getElementById("PaymentTypeId").value; if (!paymentTypeId) { Swal.fire('先に支払タイプを選択してください', '', 'warning'); return; } Swal.fire({ title: '新しい支払方法', input: 'text', inputPlaceholder: '</code></pre><p data-f-id="pbf" style="text-align: center; font-size: 14px; margin-top: 30px; opacity: 0.65; font-family: sans-serif;">Powered by <a href="https://www.froala.com/wysiwyg-editor?pb=1" title="Froala Editor">Froala Editor</a></p>
コピーする
添付画像
画像を変更
Back to List
//検索文:Editor内でHTMLコードをコピーさせる