実装するには、
以下のように View + Controller + JavaScript(AJAX) を組み合わせるのが一般的です。
1. データモデル例
親(Category)と子(SubCategory)のリレーションを想定します。
// Models/Category.cs
public class Category
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public ICollection<SubCategory> SubCategories { get; set; } = new List<SubCategory>();
}
// Models/SubCategory.cs
public class SubCategory
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public int CategoryId { get; set; }
public Category Category { get; set; } = null!;
}
2. DbContext 設定
// Data/AppDbContext.cs
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<Category> Categories { get; set; }
public DbSet<SubCategory> SubCategories { get; set; }
}
3. コントローラー
// Controllers/ProductController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
public class ProductController : Controller
{
private readonly AppDbContext _context;
public ProductController(AppDbContext context)
{
_context = context;
}
// 初期表示
public IActionResult Create()
{
ViewBag.Categories = _context.Categories.ToList();
return View();
}
// 子カテゴリ取得API (AJAX用)
[HttpGet]
public IActionResult GetSubCategories(int categoryId)
{
var subCategories = _context.SubCategories
.Where(sc => sc.CategoryId == categoryId)
.Select(sc => new { sc.Id, sc.Name })
.ToList();
return Json(subCategories);
}
}
4. View (Razor)
@{
ViewData["Title"] = "2階層セレクト";
}
<h2>商品登録</h2>
<form>
<div>
<label>カテゴリ</label>
<select id="CategoryId" name="CategoryId" class="form-control">
<option value="">-- 選択してください --</option>
@foreach (var cat in ViewBag.Categories)
{
<option value="@cat.Id">@cat.Name</option>
}
</select>
</div>
<div>
<label>サブカテゴリ</label>
<select id="SubCategoryId" name="SubCategoryId" class="form-control">
<option value="">-- 先にカテゴリを選択 --</option>
</select>
</div>
</form>
@section Scripts {
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function () {
$('#CategoryId').change(function () {
var categoryId = $(this).val();
var subCategorySelect = $('#SubCategoryId');
subCategorySelect.empty();
if (categoryId) {
$.getJSON('/Product/GetSubCategories', { categoryId: categoryId }, function (data) {
subCategorySelect.append($('<option>').text('-- 選択してください --').attr('value', ''));
$.each(data, function (i, item) {
subCategorySelect.append($('<option>').text(item.name).attr('value', item.id));
});
});
} else {
subCategorySelect.append($('<option>').text('-- 先にカテゴリを選択 --').attr('value', ''));
}
});
});
</script>
}
5. 実装ポイント
- 親セレクトは初期表示時に
ViewBag で全件取得。 - 子セレクトは親の選択変更イベントで AJAX により取得。
- Controller の
GetSubCategories は JSON を返すだけにして軽量化。 - jQuery を使わずに
fetch API でも実装可能。
✅ この方法なら、
- ページリロードなしで子セレクトが切り替わる
- データベースの内容に応じて動的に選択肢が変わる
- 親子関係が増えても拡張しやすい
もし希望があれば、このコードを jQueryなしの純JavaScript版 に書き換えた実装もできますが、
Powered by Froala Editor