カスケーディング ドロップダウンリスト 2

2017/11/29
ポストバック時に選択を保持するために書き直しました。

連動するドロップダウンリストを複数設置して絞込み、絞り込まれたカテゴリーで抽出結果をドロップダウンの下にテーブルで表示、という案件。
一から書くならボタンを押さずにプルダウン切り替えで画面が変わるよう、JavaScriptのフレームワーク使ってSPAするのがユーザーに優しく後々のメンテナンスも楽でしょう。
しかし、ASP.NET MVCの更新系プログラムが既にあり、そこに絞込み用のドロップダウンリストを追加したい、しかも2個追加し連動させたい、既存のコードをあまり変えたくないのでドロップダウン選択後「抽出」ボタン押してもらえばええやん、という時用に。
(※例外処理はまったくしていないのでご注意ください)

モデル

ViewでやっていたGoodsListのセットをモデルに変更。
Get用(未選択時)とPost用(選択されたIDあり)で切り替えます。
public class DDLViewModel
{
    public DDLViewModel()
    {
        this.CategoryList = getCategoryList();
        this.GoodsList = new SelectList(new SelectListItem[] { new SelectListItem { Text = "選択してください", Value = string.Empty } }, "Value", "Text");
    }

    public DDLViewModel(string selectCategoryId, string selectGoodsId)
    {
        this.SelectCategoryId = selectCategoryId;
        this.SelectGoodsId = selectGoodsId;
        this.CategoryList = getCategoryList();
        this.GoodsList = getGoodsList();
    }

    [Display(Name = "分類")]
    [Required]
    public string SelectCategoryId { get; set; }

    [Display(Name = "商品")]
    [Required]
    public string SelectGoodsId { get; set; }

    public SelectList CategoryList { get; set; }

    public SelectList GoodsList { get; set; }

    private SelectList getCategoryList()
    {
        return new SelectList(WorkerService.GoodsService.GetCategory().OrderByDescending(c => c.Id).ToArray(),
                            "Id",
                            "Name");
    }

    private SelectList getGoodsList()
    {
        return new SelectList(WorkerService.GoodsService.GetGoodsByCategoryId(this.SelectCategoryId).ToArray(),
                            "Id",
                            "Name");
    }
}

View

SelectGoodsId用のDropDownListForが変わっただけ。
@model Sample.Models.DDLViewModel
@{
    ViewBag.Title = "Index";
}
<h2>カスケーディング ドロップダウンリスト</h2>
<div>
    @using (Html.BeginForm())
    {
        <div class="form-group">
            @Html.LabelFor(m => m.SelectCategoryId)
            @Html.DropDownListFor(m => m.SelectCategoryId, Model.CategoryList, "選択してください", new { @class = "form-control", id = "CategoryList" })
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.SelectGoodsId)
            @Html.DropDownListFor(m => m.SelectGoodsId, Model.GoodsList, new { @class = "form-control", id = "GoodsList" })
        </div>
        <div>
            <input type="submit" value="送信" class="btn btn-primary" />
        </div>
    }
</div>
@section scripts{
     <script>
         $('#CategoryList').change(function () {
             var URL = '/api/goods/GetGoodsById';
             $.getJSON(URL + '/' + $('#CategoryList').val(), function (data) {
                 var items = '<option>選択してください</option>';
                 $.each(data, function (i, goods) {
                     items += "<option value='" + goods.Id + "'>" + goods.Name + "</option>";
                 });
                 $('#GoodsList').html(items);
             });
         });
     </script>
}

Controller

HttpPost用を追加
[HttpGet]
public ActionResult Index()
{
    var model = new DDLViewModel();
    return View(model);
}

[HttpPost]
public ActionResult Index(string SelectCategoryId, string SelectGoodsId)
{
    var model = new DDLViewModel(SelectCategoryId, SelectGoodsId);
    return View(model);
}
OK キャンセル 確認 その他