ASP.NET MVC での HTML5 と jQuery UI Datepicker ポップアップ カレンダーの使用 - パート 4

作成者: Rick Anderson

このチュートリアルでは、ASP.NET MVC Web アプリケーションでエディター テンプレート、表示テンプレート、jQuery UI Datepicker ポップアップ カレンダーを操作する方法の基本について説明します。

日付を編集するためのテンプレートの追加

このセクションでは、ASP.NET MVC が DataType 属性の Date 列挙型でマークされているモデル プロパティを編集するための UI を表示する際に適用されることになる日付を編集するためのテンプレートを作成します。 このテンプレートによってレンダリングされるのは日付だけで、時刻は表示されません。 テンプレート内では、jQuery UI Datepicker ポップアップ カレンダーを使用して、日付を編集するための方法を提供します。

まず、Movie.cs ファイルを開き、次のコードに示すように、Date 列挙型を含む DataType 属性を ReleaseDate プロパティに追加します。

[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }

このコードにより、表示テンプレートと編集テンプレートの両方に時刻なしで ReleaseDate フィールドが表示されます。 アプリケーションが Views\Shared\EditorTemplates フォルダー内、または Views\Movies\EditorTemplates フォルダー内に date.cshtml テンプレートを含んでいる場合、そのテンプレートは編集中に DateTime プロパティをレンダリングするために使用されます。 それ以外の場合、組み込みの ASP.NET テンプレート システムはこのプロパティを日付として表示します。

Ctrl キーを押しながら F5 キーを押してアプリケーションを実行します。 編集リンクを選択して、リリース日の入力フィールドに表示されているのが日付だけであることを確認します。

Image of movie release date

ソリューション エクスプローラーで、Views フォルダーを展開し、Shared フォルダーを展開した後、Views\Shared\EditorTemplates フォルダーを右クリックします。

[追加] をクリックした後、[ビュー] をクリックします。 [ビューの追加] ダイアログ ボックスが表示されます。

[ビュー名] ボックスに "Date" と入力します。

[部分ビューとして作成] チェック ボックスを選択します。 [レイアウトまたはマスター ページの使用][厳密に型指定されたビューの作成] チェック ボックスが選択されていないことを確認します。

追加をクリックします。 Views\Shared\EditorTemplates\Date.cshtml テンプレートが作成されます。

次のコードを Views\Shared\EditorTemplates\Date.cshtml テンプレートに追加します。

@model DateTime
Using Date Template
@Html.TextBox("", String.Format("{0:d}", Model.ToShortDateString()),
  new { @class = "datefield", type = "date"  })

最初の行は、モデルが DateTime 型であることを宣言しています。 編集テンプレートと表示テンプレートでモデルの種類の宣言を行うことは必須ではありませんが、ビューに渡されるモデルのコンパイル時チェックを受けるためには、それを行うことがベスト プラクティスです。 (別の利点として、Visual Studio においてそのビューのモデルの IntelliSense を使用できることがあります。)モデル型が宣言されていない場合、ASP.NET MVC はモデル型が動的であるとみなし、コンパイル時の型チェックを行いません。 モデルを DateTime 型として宣言すると、厳密に型指定されます。

2 行目は、日付フィールドの前に "Using Date Template" を表示する単なるリテラル HTML マークアップです。 この行を一時的に使用して、この日付テンプレートが使用されていることを確認します。

次の行は、テキスト ボックスである input フィールドをレンダリングする Html.TextBox ヘルパーです。 ヘルパーの 3 番目のパラメーターは、匿名型を使用してテキスト ボックスのクラスを datefield に、型を date に設定します。 (class は C# では予約されているため、C# パーサーでは @ 文字を使用して class 属性をエスケープする必要があります。)

date 型は、HTML5 対応ブラウザーが HTML5 カレンダー コントロールをレンダリングできるようにする HTML5 入力型です。 後で、datefield クラスを使用して jQuery Datepicker を Html.TextBox 要素にフックするための JavaScript を追加します。

Ctrl キーを押しながら F5 キーを押してアプリケーションを実行します。 次の図に示すように、テンプレートが ReleaseDate テキスト入力ボックスの直前に "Using Date Template" と表示していることから、編集ビューの ReleaseDate プロパティが編集テンプレートを使用していることを確認できます。

Image verifying template used

ブラウザーで、ページのソースを表示します。 (たとえば、ページを右クリックし、[ソースの表示] を選択します。)次の例はページのマークアップの一部を示したもので、レンダリングされた HTML の class および type 属性を表しています。

<input class="datefield" data-val="true" data-val-required="Date is required" 
      id="ReleaseDate" name="ReleaseDate" type="date" value="1/11/1989" />

Views\Shared\EditorTemplates\Date.cshtml テンプレートに戻り、"Using Date Template" マークアップを削除します。 完成したテンプレートは次のようになります。

@model DateTime
@Html.TextBox("", String.Format("{0:d}", Model.ToShortDateString()),
  new { @class = "datefield", type = "date" })

NuGet を使用した jQuery UI Datepicker ポップアップ カレンダーの追加

このセクションでは、日付編集テンプレートに jQuery UI Datepicker ポップアップ カレンダーを追加します。 jQuery UI ライブラリは、アニメーション、高度な効果、カスタマイズ可能なウィジェットのサポートを提供しています。 これは jQuery JavaScript ライブラリの上に構築されています。 Datepicker ポップアップ カレンダーを使用すると、文字列を入力する代わりにカレンダーを使用して日付を簡単かつ自然に入力できます。 また、ポップアップ カレンダーは、ユーザーの入力を有効な日付に制限します。通常の日付のテキスト入力では 2/33/1999 (1999 年 2 月 33 日) のようなものを入力できますが、jQuery UI Datepicker ポップアップ カレンダーはこれをできなくします。

まず、jQuery UI ライブラリをインストールする必要があります。 そのためには NuGet を使用します。これは Visual Studio 2010 と Visual Web Developer の SP1 バージョンに含まれるパッケージ マネージャーです。

Visual Web Developer で、[ツール] メニューから [NuGet パッケージ マネージャー] を選択した後、[NuGet パッケージの管理] を選択します。

Image showing how to access Manage Nu Get Packages menu option

注: [ツール] メニューに NuGet パッケージ マネージャー コマンドが表示されない場合は、NuGet Web サイトの NuGet のインストール ページの手順に従って NuGet をインストールする必要があります。

Visual Web Developer ではなく Visual Studio を使用している場合は、[ツール] メニューから [NuGet パッケージ マネージャー] を選択した後、[ライブラリ パッケージ参照の追加] を選択します。

Image showing Visual Studio version to access Nu Get Package manager

[MVCMovie - NuGet パッケージの管理] ダイアログ ボックスで、左側の [オンライン] タブをクリックした後、検索ボックスに "jQuery.UI" と入力します。 [jQuery UI Widgets:Datepicker] を選択した後、[インストール] ボタンを選択します。

Image showing j Query U I date picker

Image 2

NuGet は、以下に示す jQuery UI Core と jQuery UI Datepicker のデバッグ バージョンと縮小バージョンをプロジェクトに追加します。

  • jquery.ui.core.js
  • jquery.ui.core.min.js
  • jquery.ui.datepicker.js
  • jquery.ui.datepicker.min.js

注: デバッグ バージョン (.min.js 拡張子のないファイル) はデバッグには役立ちますが、運用サイトでは縮小バージョンのみを含めることになります。

jQuery Datepicker を実際に使用するには、カレンダー ウィジェットを編集テンプレートにフックする jQuery スクリプトを作成する必要があります。 ソリューション エクスプローラーで、Scripts フォルダーを右クリックし、[追加][新しいアイテム][JScript ファイル] の順に選択します。 ファイルに DatePickerReady.js という名前を付けます。

DatePickerReady.js ファイルに次のコードを追加します。

$(function () {
    $(".datefield").datepicker(); 
});

jQuery に慣れていない場合のために何を行っているかを簡単に説明すると、次のようになります: 最初の行は "jQuery ready" 関数であり、これはページ内のすべての DOM 要素が読み込まれたときに呼び出されます。 2 行目は、datefield というクラス名を持つすべての DOM 要素を選択した後、各要素に対して datepicker 関数を呼び出します。 (このチュートリアルの前半で Views\Shared\EditorTemplates\Date.cshtml テンプレートに datefield クラスを追加したことを思い出してください。)

次に、Views\Shared\_Layout.cshtml ファイルを開きます。 以下のファイルへの参照を追加する必要があります。これらはすべて Datepicker を使用するために必要です。

  • Content/themes/base/jquery.ui.core.css
  • Content/themes/base/jquery.ui.datepicker.css
  • Content/themes/base/jquery.ui.theme.css
  • jquery.ui.core.min.js
  • jquery.ui.datepicker.min.js
  • DatePickerReady.js

次の例は、Views\Shared\_Layout.cshtml ファイルの head 要素の下部に追加する必要がある実際のコードを示しています。

<link href="@Url.Content("~/Content/themes/base/jquery.ui.core.css")" 
        rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" 
        rel="stylesheet"  type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.theme.css")" 
        rel="stylesheet" type="text/css" />

    <script src="@Url.Content("~/Scripts/jquery.ui.core.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.datepicker.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/DatePickerReady.js")" 
        type="text/javascript"></script>

完全な head セクションを次に示します。

<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" 
        rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" 
        type="text/javascript"></script>

    <link href="@Url.Content("~/Content/themes/base/jquery.ui.core.css")" 
        rel="stylesheet" type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" 
        rel="stylesheet"  type="text/css" />
    <link href="@Url.Content("~/Content/themes/base/jquery.ui.theme.css")" 
        rel="stylesheet" type="text/css" />

    <script src="@Url.Content("~/Scripts/jquery.ui.core.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.ui.datepicker.min.js")" 
        type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/DatePickerReady.js")" 
        type="text/javascript"></script>
</head>

URL コンテンツ ヘルパー メソッドは、リソース パスを絶対パスに変換します。 アプリケーションが IIS で実行されているときにこれらのリソースを正しく参照するためには、@URL.Content を使用する必要があります。

Ctrl キーを押しながら F5 キーを押してアプリケーションを実行します。 編集リンクを選択した後、挿入ポイントを ReleaseDate フィールドに配置します。 jQuery UI ポップアップ カレンダーが表示されます。

Image of release date field with date picker

大部分の jQuery コントロールと同様に、Datepicker では広範なカスタマイズが可能です。 詳細については、jQuery UI サイト上の「ビジュアルのカスタマイズ: jQuery UI テーマの設計」を参照してください。

HTML5 日付入力コントロールのサポート

HTML5 をサポートするブラウザーが増えるにつれ、date 入力要素などのネイティブ HTML5 入力を使用し、jQuery UI カレンダーは使用しないようにしたくなるでしょう。 ブラウザーが HTML5 コントロールをサポートしている場合にはそれを自動的に使用するためのロジックをアプリケーションに追加できます。 そのためには、DatePickerReady.js ファイルの内容を次のように置き換えます。

if (!Modernizr.inputtypes.date) {
    $(function () {
        $(".datefield").datepicker();
    });
}

このスクリプトの最初の行は、Modernizr を使用して HTML5 日付入力がサポートされていることを確認します。 サポートされていない場合は、代わりに jQuery UI Datepicker がフックされます。 (Modernizr は、HTML5 と CSS3 のネイティブ実装の利用可能性を検出するオープンソース JavaScript ライブラリです。Modernizr は、作成するどの新しい ASP.NET MVC プロジェクトにも含まれています。)

この変更を行った後は、Opera 11 などの HTML5 をサポートするブラウザーを使用してそれをテストできます。 HTML5 互換ブラウザーを使用してアプリケーションを実行し、ムービー エントリを編集します。 以下のように、jQuery UI ポップアップ カレンダーの代わりに HTML5 日付コントロールが使用されます。

Image of H T M L 5 date control

新しいバージョンのブラウザーは HTML5 を段階的に実装しているため、現時点での良いアプローチは、さまざまな HTML5 サポートに対応するコードを Web サイトに追加することです。 たとえば、以下に示すのは HTML5 日付コントロールを部分的にしかサポートしないブラウザーをサイトがサポートできるようにするより堅牢な DatePickerReady.js スクリプトです。

if (!Modernizr.inputtypes.date) {
    $(function () {
        $("input[type='date']")
                    .datepicker()
                    .get(0)
                    .setAttribute("type", "text");
    })
}

このスクリプトは、HTML5 日付コントロールを完全にはサポートしていない型が date である HTML5 input 要素を選択します。 これらの要素に対しては、jQuery UI ポップアップ カレンダーをフックした後、type 属性を date から text に変更します。 type 属性を date から text に変更することで、部分的な HTML5 の日付サポートが削除されます。 さらに堅牢な DatePickerReady.js スクリプトは、「JSFIDDLE」で確認できます。

テンプレートへの Null 許容日付の追加

既存の日付テンプレートのいずれかを使用し、null 値の日付を渡すと、実行時エラーが発生します。 日付テンプレートをより堅牢にするために、null 値を処理するようにこれらを変更します。 Null 許容日付をサポートするには、Views\Shared\DisplayTemplates\DateTime.cshtml のコードを次のように変更します。

@model Nullable<DateTime>
@(Model != null ? string.Format("{0:d}", Model) : string.Empty)

このコードは、モデルが null 値である場合に空の文字列を返します。

Views\Shared\EditorTemplates\Date.cshtml のコードを次のように変更します。

@model Nullable<DateTime>

 @{
    DateTime dt = DateTime.Now;
    if (Model != null)
    {
       dt  = (System.DateTime) Model;
   
    }
    @Html.TextBox("", String.Format("{0:d}", dt.ToShortDateString()), new { @class = "datefield", type = "date"  })
}

このコードを実行すると、モデルが null 値でない場合は、モデルの DateTime 値が使用されます。 モデルが null 値である場合は、代わりに現在の日付が使用されます。

まとめ

このチュートリアルでは、ASP.NET テンプレート ヘルパーの基本について説明し、ASP.NET MVC アプリケーションで jQuery UI Datepicker ポップアップ カレンダーを使用する方法を示しました。 詳細については、以下のリソースを試してください。

  • jQuery UI については、「jQuery UI」を参照してください。
  • Datepicker コントロールをローカライズする方法については、「UI/Datepicker/Localization」を参照してください。
  • ASP.NET MVC テンプレートの詳細については、ASP.NET MVC 2 テンプレートに関する Brad Wilson のブログ シリーズを参照してください。 このシリーズは ASP.NET MVC 2 を対象に記述されていますが、この資料は現在のバージョンの ASP.NET MVC でも有効です。