ASP.NET 徹底活用術のホームへ戻る

■データコントロールの応用編

 

データコントロールにクライアント側で動作するJavaScriptを組み込む場合、データコントロールの種類によって組み込み方が異なります。ここでは、RepeaterDataListDataGridJavaScriptを組み込む手順を説明します。また、後半ではデータコントロールにCSSを適用する方法とCSSをブラウザ別に分離して管理する方法についても説明します。

 

Repeaterの行をハイライトさせる (rp2.aspx)

 

Repeaterの行にマウスを移動したときに、行をピンクでハイライトさせるように改善します。新規フォームを作成して、ツールボックスからRepeaterをドラッグ&ドロップします。Repeater1のオブジェクトが作成されたら、HTMLビューに切り替えて、HeaderTemplateItemTemplateFooterTemplateを追加します。HeaderTemplateには、HTML<table>を追加します。また、ヘッダーに「得意先」を表示するために、HTML<tr>…<.tr><td>…</td>を追加します。FooterTemplateには、HTML</table>を追加します。

 

ItemTemplateには、HTML<tr>…</tr><td>…</td>を追加して得意先テーブルのフィールドをバインドします。表(table)の行(tr)にマウスを移動したときに行をハイライトさせるには、クライアント側で動作するonmouseoveronmouseoutイベントを使用します。Onmouseoverイベントは、対象となるコントロール上にマウスを移動したときに発生します。Onmouseoverイベントは、対象となるコントロールの外にマウスを移動したときに発生します。

 

ここでは、Repeaterの行を対象コントロールとしたいので、<tr>onmouseoveronmouseoutイベントを追加します。Onmouseoverイベントでは、<tr>style属性のbackgroundプロパティにpinkを設定して、背景色をピンクに書き換えています。Onmouseoutイベントでは、<tr>style属性のbackgroundプロパティにwhiteを設定して背景色を元の状態に復元しています。

 

<tr onmouseover="this.style.background='pink'"

  onmouseout="this.style.background='white'">

・・・

</tr>

 

ブラウザにWebページを表示して、マウスをRepeaterの行に移動すると背景色がピンクに変化します。マウスを行の外に移動すると、背景色が白に復元されます。このサンプルは、Internet Explorer 6.0Firefox 1.0などのブラウザで動作します。その他のブラウザや、ブラウザのバージョンによっては動作しないことがありますので本番で稼動するWebアプリケーションを開発するときは、対象ブラウザとバージョン番号など前提条件を明確にする必要があります。

 

 

図9:マウスを移動すると行の背景色がピンクになる

 

 

リスト9:HTML<tr>onmouseoveronmouseoutイベントを追加

<asp:repeater id="Repeater1" runat="server">

  <HeaderTemplate>

    <table border="0" cellpadding="10">

      <tr>

        <td>得意先</td>

      </tr>

  </HeaderTemplate>

  <ItemTemplate>

    <tr onmouseover="this.style.background='pink'"

      onmouseout="this.style.background='white'">

      <td>

    ・・・

      </td>

    </tr>

  </ItemTemplate>

  <FooterTemplate>

    </table>

  </FooterTemplate>

</asp:repeater>

 

 

DataListの行をハイライトさせる (dl2.aspx)

 

DataListRepeatLayoutプロパティにTableを設定すると、HTML<table>が自動的に生成されます。このため、Repeaterのようにテンプレートに<table>…</table>を埋め込むことはできません。ここでは、<tr>にイベントを追加する代わりに、HTML<div>onmouseoveronmouseoutイベントを追加します。Onmouseoverでは、<div>の背景色を黄色に書き換えています。Onmouseoutでは、<div>の背景色を白色に復元しています。

 

<ItemTemplate>

  <div onmouseover="this.style.backgroundColor='yellow'"

    onmouseout="this.style.backgroundColor='white'">

  ・・・

  </div>

</ItemTemplate>

 

Note DataListではDataListItemAttributes.Addメソッドで追加できない

DateListRepeatLayoutプロパティにTableを設定すると、HTML<table>が生成されます。ところが、DataListItemCreatedイベントで、DataListItemonmouseoveronmouseoutイベントを追加しても無効になります。

 

Private Sub DataList1_ItemCreated(...) Handles DataList1.ItemCreated

  If e.Item.ItemType = ListItemType.Item OrElse _

    e.Item.ItemType = ListItemType.AlternatingItem Then

    e.Item.Attributes.Add("onmouseover", "this.style.backgroundColor='Yellow'") 無効になる

    e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor='White'")   無効になる

  End If

End Sub

 

 

 

リスト10HTML<div>onmouseoveronmouseoutイベントを追加

<asp:datalist id="DataList1" runat="server"

  RepeatColumns="3" RepeatDirection="Horizontal"...>

  <HeaderTemplate>

    得意先リスト

  </HeaderTemplate>

  <ItemTemplate>

    <div onmouseover="this.style.backgroundColor='yellow'"

      onmouseout="this.style.backgroundColor='white'">

   ・・・

    </div>

  </ItemTemplate>

</asp:datalist>

 

DataGridの行をハイライトさせる (dg2.aspx)

 

DataGridは、HTML<table>が自動生成されます。<table><tr>…</tr>onmouseoveronmouseoutイベントを追加するには、ItemCreatedイベントを使用します。ItemCreatedイベントは、DataGridDataGridItemが作成されたときに発生します。このイベントには、ヘッダー、フッターも渡りますのでe.ItemTypeプロパティを参照してカレントがアイテムか調べます。<tr>にイベントを追加するには、DataGridItemAttributesコレクションのAddメソッドを使用します。Addメソッドの引数には、イベント名とイベントの処理をJavaScriptで記述します。Onmouseoverイベントでは、<tr>style属性のbackgroundcolorプロパティにPinkを設定して背景色を書き換えています。Onmouseoutイベントでは、<tr>style属性のbackgroudcolorプロパティを元の状態に復元しています。DataGridItemが奇数行のときは背景色をLightGoldenrodYellowに、偶数行のときは背景色をPaleGoldenrodに復元します。奇数行と偶数行の背景色が異なる点に注意してください。

 

If e.Item.ItemType = ListItemType.Item Then

  e.Item.Attributes.Add("onmouseover", "this.style.backgroundColor='Pink'")

  e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor='LightGoldenrodYellow'")

ElseIf e.Item.ItemType = ListItemType.AlternatingItem Then

  e.Item.Attributes.Add("onmouseover", "this.style.backgroundColor='Pink'")

  e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor='PaleGoldenrod'")

End If

 

 

リスト11: DataGridItemonmouseoveronmouseoutイベントを追加

Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated

  If e.Item.ItemType = ListItemType.Item Then

    e.Item.Attributes.Add("onmouseover", "this.style.backgroundColor='Pink'")

    e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor='LightGoldenrodYellow'")

  ElseIf e.Item.ItemType = ListItemType.AlternatingItem Then

    e.Item.Attributes.Add("onmouseover", "this.style.backgroundColor='Pink'")

    e.Item.Attributes.Add("onmouseout", "this.style.backgroundColor='PaleGoldenrod'")

  End If

End Sub

 

 

CSSを利用して行をハイライトさせる

 

プログラム中にハイライトするカラーコードを直接記述すると保守性がよくないのでお勧めできません。ここでは、CSSを使用して保守性を改善します。

 

○ステップ1- Firefox版 (dg3fx.aspx

 

CSSには、:link:visited:hover:active:focusなどの擬似クラスがサポートされています。:hoverは、カーソルを要素上に移動した時にそのスタイルを適用します。たとえば、HTML<head>…</head>の間に、次のようなスタイルを追加して、マウスを<tr>…</tr>上に移動したときに背景色がピンクに変わります。マウスを<tr>…</tr>の外に移動すると元の背景色に復元されます。

 

<style>

  tr:hover { background-color:pink; }  /* <tr>に擬似クラス:hoverを指定 */

</style>

 

<table>

  <tr>

    <td>セル</td>

  </tr>

</table>

 

すべての<tr>に擬似クラス:hoverを適用させると、DataGridのヘッダーとフッターの背景色もピンクに変わってしまいます。この不都合を回避するには、<tr>CSSのクラス名を追加して対象となる<tr>を限定します。たとえば、<table>のアイテムの行のみ適用するにはアイテムの<tr>class="hilight"を追加します。

 

<style>

  tr.hilight:hover { background-color:pink; }  /* <tr>にクラス名+擬似クラスを指定 */

</style>

 

<table>

  <tr><td>ヘッダー</td> </tr>

  <tr class="hilight"><td>アイテム</td> </tr>  <!--この行にのみスタイルを適用させる -->

  <tr><td>フッター</td></tr>

</table>

 

DataGridの奇数行と偶数行の<tr>…</tr>CSSのクラス名を追加するには、ItemStyleAlternatingItemStyleCssClassプロパティにクラス名を設定します。

 

<ItemStyle CssClass="hilight"></ItemStyle>

<AlternatingItemStyle CssClass="hilight"></AlternatingItemStyle>

 

Note Internet Explorer<tr>の擬似クラス:hoverが無効となる

Internet ExplorerFirefoxと異なり、<tr>に擬似クラス:hoverを指定しても無効になります。Internet Explorerは、<a>タグに対してのみ擬似クラス:hoverが有効ですからこの方式は適用できません。

 

 

リスト12:CSSの擬似クラス:hoverを使用して行をハイライトする(Firefox)

<head>

  <style type="text/css">

    tr.hilight:hover { background-color:pink; }

  </style>

</head>

 

<asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns="False"

  BackColor="LightGoldenrodYellow" ForeColor="Black"...>

  <ItemStyle CssClass="hilight"></ItemStyle>

  <AlternatingItemStyle CssClass="hilight" BackColor="PaleGoldenrod"></AlternatingItemStyle>

  <Columns>

  ・・・

  </Columns>

</asp:DataGrid>

 

 

○ステップ2 -  Internet Explorer版 (dg3IE.aspx

 

Internet ExplorerCSSを使用するには、擬似クラス:hoverと同等機能をクライアント側のonmouseoveronmouseoutイベントを利用して実現します。<tr>…</tr>の行にマウスを移動するとonmouseoverイベントが発生して、<tr>class属性をoverに書き換えます。このとき、CSStr.overが適用されて背景色がピンクに変わります。マウスを<tr>…</tr>の行外に移動すると、onmouseoutイベントが発生して、<tr>class属性を無効にします。このとき、CSStr.overが適用されませんので背景色が復元されます。

 

<style type="text/css">

  tr.over { background-color:pink; }  /* <tr>にクラスoverを指定 */

</style>

 

<table>

  <tr onmouseover="this.className='over';"

    onmouseout="this.className='';">

    <td>アイテム</td>

  </tr>

</table>

 

DataGridが自動生成したHTML<tr>にクライアント側で動作するonmouseoveronmouseoutイベントを追加するには、ItemCreatedイベントを利用します。DataGridItemItemTypeItemおよびAlternatingItemならDataGridItemAttributesコレクションのAddメソッドでonmouseoveronmouseoutイベントを追加します。

 

If e.Item.ItemType = ListItemType.Item OrElse _

  e.Item.ItemType = ListItemType.AlternatingItem Then

  e.Item.Attributes.Add("onmouseover", "this.className='over';")

  e.Item.Attributes.Add("onmouseout", "this.className='';")

End If

 

Internet ExplorerWebページを表示してマウスをDataGridの奇数行に移動すると背景色がピンクに変わります。ところがマウスを偶数行に移動したときは背景色が変わりません。そこで、ブラウズに表示されたWebページのHTMLソースを調べてみると、偶数行の<tr>にはstyle属性が追加されているのがわかります。<tr>class=style=CSSを重複して指定したときは、インラインのstyle=が優先されます。このため、onmouseoverイベントで<tr>class属性をoverに書き換えても、CSStr.overは適用されません。

 

<!-- DataGridの奇数行 -->

<tr onmouseover="this.className='over';" onmouseout="this.className='';">

  <td>1</td><td>喫茶たいむましん</td><td>林  千春</td><td>(0952)26-64XX</td>

</tr>

<!-- DataGridの偶数行 -->

<tr onmouseover="this.className='over';" onmouseout="this.className='';"

  style="background-color:PaleGoldenrod;">

  <td>2</td><td>小料理なんごく</td><td>河本 なみ</td><td>(0988)55-87XX</td>

</tr>

 

この不都合を回避するには、CSStr.over td {…}のように書き換えます。tr.over+半角スペース+tdのようにCSSのセレクタを組み合わせると親子関係をもたせることができます。たとえば、DataGridの偶数行にマウスを移動するとonmouseroverイベントが発生して<tr>class=overに書き換えます。このとき、CSSの親のセレクタtr.overではなく子供のセレクタ tdにスタイルが適用されて、<td>の背景色がピンクに変わります。<td>には、style=が追加されていませんのでCSSが重複しません。

 

<style type="text/css">

  tr.over td { background-color:pink; } /* tr.overの子供tdにスタイルを適用させる */

</style>

 

 

リスト13:CSSのクラスoverを使用して行をハイライトする(IE)

<head>

  <style type="text/css">

    tr.over td { background-color:pink; }

  </style>

</head>

 

Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated

  If e.Item.ItemType = ListItemType.Item OrElse _

    e.Item.ItemType = ListItemType.AlternatingItem Then

    e.Item.Attributes.Add("onmouseover", "this.className='over';")

    e.Item.Attributes.Add("onmouseout", "this.className='';")

  End If

End Sub

 

 

○ステップ3 - Internet Explorer/Firefox双方に対応させる (dg3.aspx

 

Internet ExplorerFirefoxに対応したWebページを作成するには、CSSの外部ファイルをブラウザ別に作成します。外部ファイルdg3IE.cssにはIE 6.0用のCSSdg3Forefox.cssにはFirefox 1.0用のCSSを格納します。

 

HTML<head>…</head>の間にCSSの外部ファイルを取り込む<link>タグを追加します。なお、<link>href属性は、ランタイム時に追加しますので指定しません。<link>には、id=runat=を追加してサーバーコントロールとします。なお、<link>をサーバーコントロールとしたときは必ず終了タグの</link>を追加します。

 

<link id="dg3Style" runat="server" rel="stylesheet" type="text/css"></link>

 

Page_Loadイベントでは、HttpBrowserCapabilitiesオブジェクトのBrowserプロパティを参照してブラウザの種類を調べます。BrowserプロパティがIE(Internet Explorer)のときは、<link>href=dg3IE.cssを追加します。Netscape(Firefox)のときは、<link>href=dg3Firefox.cssを追加します。これで、使用中のブラウザに対応したCSSが外部ファイルからロードされます。

 

なお、<link>href=属性を追加するには、次のWithEventsを追加することを忘れないでください。

 

Protected WithEvents dg3Style As System.Web.UI.HtmlControls.HtmlGenericControl

 

If Request.Browser.Browser = "IE" Then

  dg3Style.Attributes("href") = "dg3IE.css"

ElseIf Request.Browser.Browser = "Netscape" Then

  dg3Style.Attributes("href") = "dg3Firefox.css"

End If

 

DataGridItemCreatedイベントでは、ブラウザがIE(Internet Explorer)のときのみDataGirdItemonmouseoveronmouseoutイベントを追加するように改善します。

 

If Request.Browser.Browser = "IE" Then

  e.Item.Attributes.Add("onmouseover", "this.className='over';")

  e.Item.Attributes.Add("onmouseout", "this.className='';")

End If

 

 

Tip <meta>タグのkeywordをランタイム時に生成する

<meta name="keyword">タグにid=runat=を追加してサーバーコントロールにすると、ランタイム時にキーワードをダイナミックに生成することができます。また、キーワードをデータベースから取り込むように設計するとプログラムを変更せずにキーワードを自由に書き換えることができますからSEO対策に最適です。なお、<meta>タグをサーバーコントロールとするときは、必ず終了タグ</meta>を追加してください。

 

<meta id="myKeyword" runat="server" name="keyword"></meta>

 

Protected WithEvents myKeyword As System.Web.UI.HtmlControls.HtmlGenericControl

myKeyword.Attributes("content") = "asp.net, ado.net"  キーワードをダイナミックに追加

 

 

 

図10: Internet ExplorerDataGridの行をハイライトした例

 

図11: FirefoxDataGridの行をハイライトした例

 

リスト14:IEFirefoxCSSを外部ファイルとして別々に作成する

/*

** dg3IE.css -  IE6.0CSS

*/

tr.over td { background-color : pink }

 

/*

** dg3Firefox.css - Firefox 1.0CSS

*/

tr.hilight:hover { background-color: pink }

 

 

リスト15:<head>…</head><link>を追加して外部スタイルシートを取り込む

<head>

  <link id="dg3Style" runat="server" rel="stylesheet" type="text/css"></link>

</head>

 

<asp:DataGrid id="DataGrid1" runat="server" AutoGenerateColumns="False"

  BackColor="LightGoldenrodYellow"...>

  <AlternatingItemStyle CssClass="hilight" BackColor="PaleGoldenrod"></AlternatingItemStyle>

  <ItemStyle CssClass="hilight"></ItemStyle>

  <Columns>

  ・・・

  </Columns>

</asp:DataGrid>

 

 

リスト16: Page_Loadイベントで<link>タグのhref=属性を追加する

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  If Request.Browser.Browser = "IE" Then

    dg3Style.Attributes("href") = "dg3IE.css"

  ElseIf Request.Browser.Browser = "Netscape" Then

    dg3Style.Attributes("href") = "dg3Firefox.css"

  End If

  If Not IsPostBack Then

    BindDataGrid()

  End If

End Sub

 

Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles DataGrid1.ItemCreated

  If e.Item.ItemType = ListItemType.Item OrElse _

    e.Item.ItemType = ListItemType.AlternatingItem Then

    If Request.Browser.Browser = "IE" Then

      e.Item.Attributes.Add("onmouseover", "this.className='over';")

      e.Item.Attributes.Add("onmouseout", "this.className='';")

    End If

  End If

End Sub

 

 

ASP.NET 徹底活用術のホームへ戻る