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() メソッドを適用することで可能になります。
ASP.NET MVC アプリではそれと同様なことはできないと思っていたのですが、MVC4 以降には Html ヘルパーに IdFor メソッドが用意されていて、それを使えば可能なことが分かりました。今さらながらですが(汗)、その具体例を書いておきます。
以下のような View のコードからは、
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 のもの)
<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 です)
@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 タグは一つにしたかったのですが、その方法が見つかりませんでした。(汗) 方法が分かったら追記します)
<script type="text/javascript">
//<![CDATA[
$("#Children_0__DateOfBirth").datepicker();
//]]>
</script>
<script type="text/javascript">
//<![CDATA[
$("#Children_1__DateOfBirth").datepicker();
//]]>
</script>
その結果をブラウザに表示したのが上の画像です。
(name 属性の値を取得したいというケースもあるかもしれませんが、そのための Html ヘルパー NameFor も用意されているそうです。ご参考まで)