WebSurfer's Home

APMLフィルター

Control.ClientID と Html.IdFor

by WebSurfer 2017年2月19日 14:13

ASP.NET Web Forms アプリの場合、サーバーコントロールが HTML 要素としてレンダリングされた際、その要素の id 属性の値を取得するのに ClientID プロパティを利用できます。

なので、<%=TextBox1.ClientID%> というようにコード表示ブロックを使って、インラインのスクリプトに TextBox1 が HTML 要素に変換された時の id を埋め込むことができます。

例えば Datepicker を使いたい場合、$('#<%=TextBox1.ClientID%>') として TextBox1 の jQuery オブジェクトを取得し、それに datepicker() メソッドを適用することで可能になります。

jQuery UI Datepicker

ASP.NET MVC アプリではそれと同様なことはできないと思っていたのですが、MVC4 以降には Html ヘルパーに IdFor メソッドが用意されていて、それを使えば可能なことが分かりました。今さらながらですが(汗)、その具体例を書いておきます。

以下のような View のコードからは、

1
2
3
4
5
6
7
8
9
10
for (int i = 0; i < Model.Children.Count; i++)
{
  @Html.LabelFor(m => m.Children[i].Name)
  @Html.EditorFor(m => m.Children[i].Name)
  @Html.ValidationMessageFor(m => m.Children[i].Name)
         
  @Html.LabelFor(m => m.Children[i].DateOfBirth)
  @Html.EditorFor(m => m.Children[i].DateOfBirth)
  @Html.ValidationMessageFor(m => m.Children[i].DateOfBirth)
}

以下のような html ソースがレンダリングされます。(i = 0 のもの)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<label for="Children_0__Name">Name</label>
<input class="text-box single-line"
  id="Children_0__Name" name="Children[0].Name"
  type="text" value="" />
<span class="field-validation-valid"
  data-valmsg-for="Children[0].Name"
  data-valmsg-replace="true">
</span>
<label for="Children_0__DateOfBirth">DateOfBirth</label>
<input class="text-box single-line" data-val="true"
  data-val-date="DateOfBirth は日付である必要があります。"
  data-val-required="DateOfBirth フィールドが必要です。"
  id="Children_0__DateOfBirth" name="Children[0].DateOfBirth"
  type="datetime" value="0001/01/01 0:00:00" />
<span class="field-validation-valid"
  data-valmsg-for="Children[0].DateOfBirth"
  data-valmsg-replace="true">
</span>

上記の通り HTML 要素の id は予測不能ではないものの、それをスクリプトにハードコーディングするのはやめた方がよさそうです。(命名規則が変わるかもしれないので。そのあたりの事情は ASP.NET Web Forms アプリでも同じです)

Html.IdFor メソッドを使えば HTML 要素の id を取得できます。なので、例えばテキストボックスに Datepiker を適用したい場合は、以下の for 文のようにします。(MVC4 のテンプレートでアプリを作った場合です。for 文の上の 3 行はクライアント側での検証用スクリプト、jQuery UI 用のスクリプトと CSS です)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@section Scripts {
  @Scripts.Render("~/bundles/jqueryval")
  @Scripts.Render("~/bundles/jqueryui")
  @Styles.Render("~/Content/themes/base/css")
 
  @for (int i = 0; i < Model.Children.Count; i++) {
  <script type="text/javascript">
  //<![CDATA[
    $("#@Html.IdFor(m => m.Children[i].DateOfBirth)").
        datepicker();
  //]]>
  </script>
  }
}

すると、上記 for 文のコードによって以下のようなスクリプトが生成されます。(script タグは一つにしたかったのですが、その方法が見つかりませんでした。(汗) 方法が分かったら追記します)

1
2
3
4
5
6
7
8
9
10
<script type="text/javascript">
//<![CDATA[
  $("#Children_0__DateOfBirth").datepicker();
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
  $("#Children_1__DateOfBirth").datepicker();
//]]>
</script>

その結果をブラウザに表示したのが上の画像です。

(name 属性の値を取得したいというケースもあるかもしれませんが、そのための Html ヘルパー NameFor も用意されているそうです。ご参考まで)

現在のレート 5.0 (1人)

  • Currently 5.0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

MVC

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。ブログ2はそれ以外の日々の出来事などのトピックスになっています。

Calendar

<<  2025年3月  >>
2324252627281
2345678
9101112131415
16171819202122
23242526272829
303112345

View posts in large calendar