asp.netのrepeaterで出力時にjavascriptのイベントを定義する
asp.netのrepeaterで表示・編集・登録処理を行う その2でrepeaterを使って、表示→編集→登録の一連の流れが実装できました。
今回は、表示→編集→登録のうち、編集について、もっと細かい制御を追加します。
イベントを定義する
詳細ボタンの列を追加し、クリック時にクリックした行の選手の詳細画面をポップアップで起動するという処理を追加します。
詳細画面はクエリストリングで選手のIDを受け取って表示する仕様とします。
選手名 | 国籍 | 怪我 | キャプテン | |
---|---|---|---|---|
まずはapsx
ファイルに詳細ボタンと、詳細画面を起動するjavascript
のファンクションを定義します。
<script>
//詳細画面を起動します
//id:選手のID
function showDetail(id){
//クエリストリングで選手のIDを渡します
window.open('detail.html?id=' + id, null);
}
</script>
<table>
<thead>
<tr>
<td></td>
<td>選手名</td>
<td>国籍</td>
<td>怪我</td>
<td>キャプテン</td>
</tr>
</thead>
<tbody>
<asp:Repeater ID="repeater1" runat="server">
<ItemTemplate>
<tr>
<td><input type="button" id="btnDetail" value="詳細" runat="server" /></td><!--詳細ボタンを定義します-->
<td><input type="text" id="txtName" runat="server" /></td>
<td><select id="selCountry" runat="server"></select></td>
<td><input type="checkbox" id="chkInjure" runat="server" /></td>
<td><input type="radio" id="rdoCap" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
btnDetail
のonclick
属性(イベント)をaspx
に定義してしまうと、引数で必要な選手のIDがわからないので、サーバー処理でのイベントでonclick
を定義します。
ItemDataBound
のイベントで、詳細ボタンのクリックイベントを定義します。
Sub repeater1_ItemDataBound(Byval Sender As Object, _
Byval e As RepeaterItemEventArgs) Handles repeater1.ItemDataBound
'HeaderTemplateとFooterTemplateのときは処理を飛ばします
If e.Item.ItemType = ListItemType.Item Or _
e.Item.ItemType = ListItemType.AlternatingItem Then
'現在のバインドしている行を取得します DataTableをバインドした場合はDataRowViewになります
Dim row As DataRowView = CType(e.Item.DataItem, DataRowView)
'詳細ボタンのコントロールを取得 e.Itemで現在の行のhtml(aspx)を取得できます
Dim buttonControl As HtmlInputTextBox = CType(e.Item.FindControl("btnDetail"), HtmlInputButton)
'コントロールにonclickのイベントを定義します
'引数に選手のIDを渡すようにします
buttonControl.Attributes.Add("onclick", "showDetail(" & row("ID").ToString & ");")
End If
End Sub
これで行ごとにイベントを定義することができました。
独自データ属性
今回は選手のIDだけを引数にしましたが、渡したい情報が増えたときは、その分だけ引数を増やすよりも、btnDetail
の要素に独自データ属性を定義して、btnDetail
そのもの(this
)を引数として渡すほうが簡単です。
属性とはvalue
, readonly
, disabled
など、htmlの要素の中に定義する情報です。
独自データ属性は、独自に属性を定義することができます。data-
を先頭につけて定義します。例えば選手のIDを独自データ属性で定義する場合は、data-sid
などとします。
以下のようにサーバー処理で独自データ属性を定義します。
Sub repeater1_ItemDataBound(Byval Sender As Object, _
Byval e As RepeaterItemEventArgs) Handles repeater1.ItemDataBound
'HeaderTemplateとFooterTemplateのときは処理を飛ばします
If e.Item.ItemType = ListItemType.Item Or _
e.Item.ItemType = ListItemType.AlternatingItem Then
'現在のバインドしている行を取得します DataTableをバインドした場合はDataRowViewになります
Dim row As DataRowView = CType(e.Item.DataItem, DataRowView)
'詳細ボタンのコントロールを取得 e.Itemで現在の行のhtml(aspx)を取得できます
Dim buttonControl As HtmlInputTextBox = CType(e.Item.FindControl("btnDetail"), HtmlInputButton)
'独自データ属性を定義します
buttonControl.Attributes.Add("data-sid", row("ID").ToString)
End If
End Sub
aspx
は以下のように書き換えます。
<script>
//詳細画面を起動します
//obj: btnDetailボタン
function showDetail(obj){
//クエリストリングで選手のIDを渡します
window.open('detail.html?id=' + obj.getAttribute("sid"), null);
}
</script>
<table>
<thead>
<tr>
<td></td>
<td>選手名</td>
<td>国籍</td>
<td>怪我</td>
<td>キャプテン</td>
</tr>
</thead>
<tbody>
<asp:Repeater ID="repeater1" runat="server">
<ItemTemplate>
<tr>
<!--引数が固定のため、onclickイベントは予め定義することができます-->
<td><input type="button" id="btnDetail" value="詳細" runat="server" onclick="showDetail(this);" /></td>
<td><input type="text" id="txtName" runat="server" /></td>
<td><select id="selCountry" runat="server"></select></td>
<td><input type="checkbox" id="chkInjure" runat="server" /></td>
<td><input type="radio" id="rdoCap" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
注意
data-
をつけずにsid
としてもブラウザによってはエラーにならずにうまく動きますが、将来的にdisabled
などのようにsid
という属性にhtmlで意味付けされてしまうと、うまく動かなくなるかもしれないので、data-
を先頭につけて独自データ属性ということを明示的に定義します。