2012/12/08

【ASP.NET】テンプレートを使ってカレンダー付きテキストボックスを作ってみる【MVC】

 超絶久しぶりな更新ですが、あっさりめに済ませます。いきなりですが、通常通り作った場合のサンプルを表示します。今回はコントローラーでは何もしないので省略です。

Pepoleモデル
public class People
{
    public string Name { get; set; }

    public DateTime Birthday { get; set; }
 
}

Createビュー
@model MvcApplicationTest3.Models.People
 
@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Create</h2>
 
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
 
    <fieldset>
        <legend>People</legend>
 
        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
 
        <div class="editor-label">
            @Html.LabelFor(model => model.Birthday)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Birthday)
            @Html.ValidationMessageFor(model => model.Birthday)
        </div>
 
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
 
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

実行結果

image

  当然ながらBirthdayにカーソルがあたっても何も起きません。こういう時、大抵はカレンダーが表示された方が便利がいいですよねって話です。んでMVCの場合、jqueryUIが使えるんだからUIのDatePickerを使ってみようってなるんですが、日付型が出てくるたびにいちいち定義してたら面倒ですよね?ってことでテンプレートの出番になるわけです。

 早速、ヘルパーテンプレートを作成します。テンプレートはある程度決まったルール(フォルダ名)で配置することで、自動で検索されて自動で定義されます(明示的に定義することも可能です)。何言ってんだって感じですが、まぁやってみれば分かります。

フォルダーとテンプレートファイルの追加

image

 このようにテンプレートファイルは利用するヘルパー系統フォルダー(EditorTemplates)の下にデータ型の名前で定義します(DateTime.cshtml)。今回はEditor系のテンプレートなのでEditorTemplatesというフォルダ名になっていますが、Display系のテンプレートであればDisplayTemplatesとなります。これで構築される際にEditorヘルパーでDateTime型だった場合、このテンプレートが呼び出されます。また、今回はShared配下に置いていますが、利用がそのビューに限定される場合はそのビューの配下に置くことも可能です。

 次はテンプレートの中身です。

テンプレートファイル(DateTime.cshtml)
@model System.DateTime?
 
@Html.TextBoxFor(model=>model, new { @class="datepicker"})
 
<!-- DatePicker定義 -->
<script type="text/javascript">
    $(function () {
        $('.datepicker').datepicker();
    });
</script>

 シンプルなので特に解説することもないのですが、jqueryUIの定義は他でしたほうが良さそうなのでレイアウトなり、ビューなりでやっちゃってください。ちなみにモデルはnull対策のためnull許容型にしています。

 次にテンプレートを呼び出すためにモデルのデータ型を属性で明示してやります。

Peopleモデル
public class People
{
    public string Name { get; set; }

    [DataType(DataType.DateTime)] //←これを追加
    public DateTime Birthday { get; set; }
 
}

 これで完了です。ビュー側は自動的にテンプレートが呼び出されるので変更する必要はありません。

実行結果

image

 こんな具合で望んだ通りになりました。Shared配下にテンプレートを作成したのでこれ以外のビューでもモデルにDateTime型が明示してあればビューは自動でこのテンプレートを割り当てます。

 以上、久しぶりに更新すると余計に日本語が怪しくなってる気がする…。
pagetop