jQuery UI を使用し、DropDownList に新しいカテゴリを追加する

作成者: Rick Anderson

HTML の Select タグは、固定したカテゴリ データの一覧を表示するには最適ですが、多くの場合、新しいカテゴリを追加する必要があります。 データベースのカテゴリにジャンル "Opera" を追加するとします。 このセクションでは、jQuery UI を使って、新しいカテゴリの追加に使用できるダイアログ ボックスを追加します。 次の図は、UI がブラウザーでどのように表示されるかを示したものです。

ブラウザー ウィンドウ内の UI の画像

ユーザーが [Add New Genre] リンクを選ぶと、新しいジャンル名 (および必要に応じて説明) の入力をユーザーに求めるポップアップ ダイアログ ボックスが表示されます。 次の図は、[Add Genre] ポップアップ ダイアログを示したものです。

ジャンルの追加ポップアップ ダイアログの画像

新しいジャンル名が入力されて、[Save] ボタンが選ばれると、次の処理が行われます。

  1. AJAX の呼び出しによって、ジャンル コントローラーの Create メソッドにデータをポストされ、新しいジャンルがデータベースに保存されて、新しいジャンル情報 (ジャンル名と ID) が JSON として返されます。

  2. JavaScript により、選択リストに新しいジャンル データが追加されます。

  3. JavaScript により、新しいジャンルが選択済みの項目になります。

    次の図では、Opera がデータベースに追加され、[Genre] ドロップダウン リストで選ばれています。

ドロップダウン リストの選択の画像

Views\StoreManager\Create.cshtml ファイルを開き、ジャンル マークアップを次のコードに置き換えます。

<div class="editor-field ui-widget">

     @Html.Partial("_ChooseGenre")

</div>

_ChooseGenre の部分的なビューには、新規ジャンル追加機能の実装に使われる JavaScript と jQuery をフックするためのすべてのロジックが含まれます。 コードが完成すると、アーティスト UI と同じ操作を簡単にできるようになります。

ソリューション エクスプローラーで、Views\StoreManager フォルダーを右クリックして、[追加][ビュー] の順に選びます。 [ビュー名] に「_ChooseGenre」と入力して、[追加] を選びます。 Views\StoreManager\_ChooseGenre.cshtml ファイル内のマークアップを次のように置き換えます。

@model MvcMusicStore.Models.Album

<div class="editor-label">

    @Html.LabelFor(model => model.GenreId, "Genre" )

</div>

@Html.DropDownList("GenreId", ViewBag.Genres as SelectList, String.Empty)

<a class="button" href="@Url.Content("~/Genre/Create")" 

    id="genreAddLink">Add New Genre</a>

@Html.ValidationMessageFor(model => model.GenreId)

<div id="genreDialog" class="hidden">

</div>

<script src="@Url.Content( "~/Scripts/ui/jquery.ui.combobox.js" )"></script>

<script src="@Url.Content("~/Scripts/chooseGenre.js")"></script>

1 行目では、モデルとして Album を渡すことが宣言されています。これは、作成ビューにあるモデルのステートメントとまったく同じです。 次の数行は、Label ヘルパーのマークアップです。 次の行は DropDownList ヘルパーの呼び出しであり、元の作成ビューとまったく同じです。 次の行では、Add New Genre という名前のリンクを追加し、ボタンのようにスタイルを設定しています。 ValidationMessageFor を含む行は、Create ビューから直接コピーされます。 次のようなコードがあります。

<div id="genreDialog" class="hidden">

</div>

これにより、ID が genreDialog である非表示の div が作成されます。 jQuery を使って、この div の ID genreDialog[Add Genre] ダイアログ ボックスをフックします。 最後の 2 つのスクリプト タグには、新規ジャンル追加機能の実装に使う JavaScript ファイルへのリンクが含まれます。 /Scripts/chooseGenre.js ファイルはプロジェクトで提供されており、このチュートリアルで後ほど調べます。

アプリケーションを実行して、[Add New Genre] ボタンをクリックします。 [Add Genre] ダイアログ ボックスの [Name] 入力ボックスに「Opera」と入力します。

ジャンルの追加ダイアログ ボックスの画像

[保存] ボタンをクリックします。 AJAX の呼び出しにより、Opera カテゴリが作成され、ドロップダウン リストに Opera が設定されて、選択済みのジャンルとして Opera が設定されます。

ドロップダウン リストで値が設定されている画像

アーティスト、タイトル、価格を入力して、[Create] ボタンを選びます。 8.99 ドル未満の価格を入力すると、新しいアルバムがインデックス ビューの先頭に表示されます。 新しいアルバムのエントリがデータベースに保存されたことを確認します。

新しいアルバム エントリがデータベースに保存されたことを確認している画像

1 文字だけの新しいジャンルを作成してみてください。 Models\Genre.cs ファイルの次のコードは、ジャンル名の最小と最大の長さを設定します。

[StringLength(20, MinimumLength = 2)]
public string Name { get; set; }

クライアント側の検証では、2 から 20 文字の文字列を入力する必要があることが報告されます。

クライアント側の検証の画像

新しいジャンルがデータベースと選択リストに追加される方法を調べる

Scripts\chooseGenre.js ファイルを開いて、コードを調べます。

$(function () {

    $('#genreDialog').dialog({

        autoOpen: false,

        width: 400,

        height: 300,

        modal: true,

        title: 'Add Genre',

        buttons: {

            'Save': function () {

                // Omitted 

            },

            'Cancel': function () {

                $(this).dialog('close');

            }

        }

    });

2 行目では、ID genreDialog を使って、Views\StoreManager\_ChooseGenre.cshtml ファイルの div タグにダイアログ ボックスを作成しています。 ほとんどの名前付きパラメータは、名前で内容がわかります。 autoOpen パラメータは false に設定されており、[Create Genre] ボタンを選ぶとダイアログが明示的に開きます (これについては後で説明します)。 ダイアログには、[Save][Cancel] の 2 つのボタンがあります。 [Cancel] ボタンはダイアログを閉じます。 次に示すコードは、[Save] ボタンの関数です。

'Save': function () {

    var createGenreForm = $('#createGenreForm');

    if (createGenreForm.valid()) {

        $.post(createGenreForm.attr('action'), createGenreForm.serialize(), function (data) {

            if (data.Error != '') {

                alert(data.Error);

            }

            else {

                // Add the new genre to the dropdown list and select it

                $('#GenreId').append(

                        $('<option></option>')

                            .val(data.Genre.GenreId)

                            .html(data.Genre.Name)

                            .prop('selected', true)  // Selects the new Genre in the DropDown LB

                    );

                $('#genreDialog').dialog('close');

            }

        });

    }

},

var createGenreForm は、createGenreForm の ID から選ばれます。 createGenreForm の ID は、Views\Genre\_CreateGenre.cshtml ファイルにある次のコードで設定されました。

@model MvcMusicStore.Models.Genre

@using (Html.BeginForm("Create", "Genre", FormMethod.Post, new { id = "createGenreForm" }))

{

    @*Omitted for clarity.*@

}

Views\Genre\_CreateGenre.cshtml ファイルで使わる Html.BeginForm ヘルパー オーバーロードは、フォームを送信する URL を含むアクション属性で HTML を生成します。 これは、ブラウザーでアルバム作成ページを表示し、ブラウザーのソースの表示を選んで確認できます。 次のマークアップは、生成された、フォーム タグを含む HTML を示しています。

<form action="/StoreManager/Create" method="post">

jQuery の $.post 行は、アクション属性 (/StoreManager/Create) に対して AJAX 呼び出しを行い、[Create Genre] ダイアログ ボックスのデータを渡します。 データは、新しいジャンルの名前とオプションの説明で構成されます。 AJAX 呼び出しが成功すると、新しいジャンル名と値が Select マークアップに追加され、新しいジャンルが選択済みの値として設定されます。 これは動的に生成されるマークアップであるため、ブラウザーでソースを表示して新しい選択オプションを確認することはできません。 IE 9 の F12 開発者ツールを使うと、新しい HTML を確認できます。 新しい選択オプションを見るには、インターネット エクスプローラー 9 で F12 キーを押して F12 開発者ツールを起動します。 [Create] ページに移動し、新しいジャンルを追加して、ジャンル選択リストで新しいジャンルが選ばれるようにします。 F12 開発者ツールで次のようにします。

  1. HTML タブを選択します。

  2. 更新アイコンをクリックします。
    更新アイコンの選択の画像

  3. 検索ボックスに「GenreID」と入力します。

  4. 次のアイコンを使って、
    [次へ] アイコンの選択の画像
    次の select タグに移動します。

    <select name="GenreId" id="GenreId" >
    
  5. 最後のオプション値を展開します。

展開されたビューの画像

Scripts\chooseGenre.js ファイルの次のコードを見ると、[Add New Genre] ボタンをクリック イベントに接続する方法と、[Add New Genre] ダイアログ ボックスを作成する方法がわかります。

$('#genreAddLink').click(function () {

    var createFormUrl = $(this).attr('href');  

    $('#genreDialog').html('')

    .load(createFormUrl, function () {  

        // The createGenreForm is loaded on the fly using jQuery load. 

        // In order to have client validation working it is necessary to tell the 

        // jQuery.validator to parse the newly added content

        jQuery.validator.unobtrusive.parse('#createGenreForm');

        $('#genreDialog').dialog('open');

    });

    return false;

});

1 行目で、[Add New Genre] ボタンにアタッチされるクリック関数が作成されます。 Views\StoreManager\_ChooseGenre.cshtml ファイルの次のマークアップでは、[Add New Genre] ボタンの作成方法が示されています。

<a class="button" href="@Url.Content("~/Genre/Create")" 

    id="genreAddLink">Add New Genre</a>

load メソッドは、[Add Genre] ダイアログを作成して開き、jQuery の parse メソッドを呼び出して、ダイアログに入力されたデータのクライアント検証を行います。

このセクションでは、選択リストに新しいカテゴリ データを追加するために使用できるダイアログを作成する方法について説明しました。 同じ手順に従って UI を作成し、アーティストの選択リストに新しいアーティストを追加できます。 このチュートリアルでは、ASP.NET MVC HTML ヘルパー DropDownList の使用方法の概要を説明しました。 DropDownList の使用について詳しくは、後の「その他の参照情報」セクションをご覧ください。 このチュートリアルが役に立ったかどうかをお知らせください。

その他の参照情報

共同作成者

レビュー担当者

  • Jean-Sébastien Goupil
  • Brad Wilson
  • Mike Pope
  • Tom Dykstra