マウスでポイントされたデータ グリッド行をハイライト表示する簡単な方法はじめにDataGridコントロールはデータを表示するための非常に強力で汎用的なコントロールであり、ASP.NET開発者にもお馴染みである(DataGridの扱いに慣れていない人は、まずScott Mitchellの記事「An Extensive Examination of the DataGrid Control」を読むことをお勧めする)。私はこれまで多くのプロジェクトでDataGridコントロールを使用し、DataGridの見た目をもっと良くしようとしてきた。そんな中の1つで現在Yahoo! MailやHotmailなどのサイトで利用されているのが、マウスでポイントされた行を自動的にハイライト表示するというテクニックだ。つまり、エンドユーザーがDataGridのデータ上にマウスを持ってきたときに、マウスが現在置かれているDataGrid行の背景は他の行とは違う色になるわけだ。 DataGridコントロールを拡張してこの機能を追加する方法については、既に数多くの記事が書かれているので、中にはマウスの動きに応じて行をハイライト表示する方法を既に知っている人も多いかもしれない。この方法の一例が、Scottの「Creating a Row-Selectable DataGrid Control」だ。この記事やその他の多くの記事で取り上げているのが、DataGridを拡張するカスタムASP.NETサーバーコントロールを作成するというソリューションで、カスタムサーバーコントロールから、行をハイライト表示するためのクライアントサイドスクリプトを発行するという形式だ(特に、 カスタムサーバーコントロールを作成する方法は、簡単だし役立つ情報も多い。しかし私は、もっと単純なアプローチで、標準のDataGridコントロールをいっさい変更せずに動作するようなものを作りたいと考えた。これを実現する方法は、AListApartのWebサイトで、CSSだけでドロップダウンメニューを作成する方法についての記事を読んだ後で思いついた。このコンセプトは単純で、「CSSのhoverスタイルを利用して、さまざまな階層形式のリストの表示/非表示を切り替える」というものだった。私はその単純さと斬新なコンセプトに心ひかれ、これに少し手を加えれば、DataGridの行もハイライト表示できるのではないかと思いついた。 私がどのようにクライアントサイドCSSのhover機能を利用して、標準のDataGridに行のハイライト表示機能を追加したかについて説明する。完成するまでの過程でいくつかの問題があったが、その問題と回避方法についても説明する。続きを読む前に、まず実際のデモを見ていただきたい。 はじめの一歩:DataGridにデータを表示する当然ながら、DataGrid内の行をハイライト表示するためには、操作対象となるDataGridが必要である。以下は、データをDataGridにバインドするサンプルとして作成したページのコードで、上記のデモページは、このページに機能を追加して完成させたものである。
<%@ Page Language = "C#" %>
<%@ Import Namespace = "System.Data" %>
<html>
<head>
<title>DataGrid Sample</title>
<script runat = "server">
private void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
BindGrid();
}
private void BindGrid()
{
DataTable table = new DataTable("Users");
table.Columns.Add("firstName");
table.Columns.Add("lastName");
table.Columns.Add("emailAddress");
AddRow(table, "Bugs", "Bunny", "bbunny@wb.com");
AddRow(table, "Mickey", "Mouse", "mmouse@disney.com");
AddRow(table, "Donald", "Duck", "dduck@disney.com");
AddRow(table, "Dan", "Marino", "dmarino@dolphins.com");
AddRow(table, "Steve", "Stchur", "sstchur@yahoo.com");
myGrid.DataSource = new DataView(table);
myGrid.DataBind();
}
private void AddRow(DataTable table, string firstName,
string lastName, string email)
{
DataRow row = table.NewRow();
row["firstName"] = firstName;
row["lastName"] = lastName;
row["emailAddress"] = email;
table.Rows.Add(row);
}
</script>
</head>
<body>
<asp:DataGrid id = "myGrid"
CellPadding = "5"
AutoGenerateColumns = "false"
Font-Name = "verdana"
Font-Size = "10pt"
runat = "server">
<HeaderStyle BackColor = "#336699"
ForeColor = "#ffffff" Font-Bold = "true" />
<AlternatingItemStyle BackColor = "#eeeeee" />
<Columns>
<asp:BoundColumn HeaderText = "First Name"
DataField = "firstName" />
<asp:BoundColumn HeaderText = "Last Name"
DataField = "lastName" />
<asp:BoundColumn HeaderText = "Email"
DataField = "emailAddress" />
</Columns>
</asp:DataGrid>
</body>
</html>
この時点のDataGridは、ハードコーディングされたデータにバインドされた、ごく単純なものだ。実際のデモを見てもわかるとおり、この例では 最初の実験 行を"ハイライト表示可能"にするために、まず単純に、ページ上のすべての
<style type = "text/css">
tr:hover { background-color: #ffccff; }
</style>
DataGrid内の各行は Internet Explorerでも動作するように修正 調べた結果、IEはハイパーリンク(
<style type = "text/css">
tr:hover, tr.over { background-color: #ffccff; }
</style>
当然ながら、この変更だけでは問題は解決できていない。まだ他に、DataGridの
<script language = "javascript">
startHighlight = function()
{
if (document.all && document.getElementById)
{
navRoot = document.getElementById(ID of DataGrid);
// Get a reference to the TBODY element
tbody = navRoot.childNodes[0];
for (i = 0; i < tbody.childNodes.length; i++)
{
node = tbody.childNodes[i];
if (node.nodeName == "TR")
{
node.onmouseover=function()
{
this.className = "over";
}
node.onmouseout=function()
{
this.className = this.className.replace("over", "");
}
}
}
}
}
window.onload = startHighlight;
</script>
上記のスクリプトでは、DataGridのすべての子要素について検索を開始するようブラウザに指示している(注: このコードをIEでテストすると、奇妙な点に気付く。表内の行が1行おきにしかハイライト表示されないのだ。これは、 この問題を解決するにはどうしたらいいだろうか。答えは簡単だ。 修正後のCSSは次のようになる。
<style type = "text/css">
tr:hover, tr.over td { background-color: #ffccff; }
</style>
ヘッダー行のハイライト表示の抑制IE固有の問題はこれで解決した。しかし、まだ見出し行がハイライト表示されてしまう問題が残っている。さてどうしたものか。気付いた方もいるかもしれないが、IE対応のJavaScriptのコードでは、テーブル(DataGrid)内のすべての行を1つずつループ処理している。そこで、次のように行インデックスを0ではなく1から開始して、1行目(ヘッダー行)をスキップすることでこの問題は簡単に解決する。 // In the startHighlight function... for (i = 1; i < tbody.childNodes.length; i++) { // this code stays the same } このコードをIEでテストすると、ヘッダー行をマウスでポイントしてもハイライト表示されないようになる。また、CSSスタイルシートに では、Firefox(やその他のIE以外のブラウザ)ではどうしたらよいだろうか。この問題を解決するには、特定の
<style type = "text/css">
tr.row:hover, tr.over td { background-color: #ffccff; }
</style>
このCSSでは、CSSクラスが なぜ2種類の方法を使うのか
ここでは、DataGridの行をハイライト表示するために、ブラウザの種類に応じて2種類の方法を使用した。FireFox用にはCSSのみを使用する方法、IE用にはCSSとJavaScriptを組み合わせる方法だ。しかし、2つの代表的なブラウザをサポートするために別々の方法を用意するというのも面倒な話だ。
回避するためには、前述のJavaScriptコードをFireFoxでも動くように書き直すという方法も考えられる。私もその方法を検討してみたが、やはり私はCSSの信奉者なので、CSSの方が優れたアプローチであり"正道"だと思う。JavaScriptは小手先の処理のように感じられてしまうのだ。 というわけで、私は可能な場合にはいつでも"正道"を進み、どうしても必要な場合にのみJavaScriptに頼るようにしている。もちろん、ここで紹介したJavaScriptをFireFoxで動作するように修正してもまったく問題はない。ただ個人的なポリシーとして、ここではCSSのみを使う方向性を貫いた。 ここまででは、DataGrid内の <AlternatingItemStyle BackColor = "#eeeeee" CssClass = "row" /> <ItemStyle BackColor = "#ffffff" CssClass = "row" /> まとめこれで完成である。簡単にDataGrid内の行をハイライト表示することができ、コードの量もこれまでに見たり実装したことのある他の方法よりかなり少ないはずである。ただ1つ断っておきたいのは、私が動作検証したのはIE 6.0とFirefox 1.0のみであるということだ。他のブラウザでどのような動作になるかはわからない(Netscape 7とIE 5.5ではおそらく正常に動作すると思う)。他のブラウザで正常に動作しない場合は、JavaScriptを使うことになる。紹介したコードを修正するだけで、きっと正常に動作するようになるだろう。 最後になったが、本稿のJavaScriptコードは私が作成したものではない。私が一部修正を加えているものの、大部分はAListApart.Comに掲載されたPatrick GriffithsとDan Webbの記事「Suckerfish Dropdown」から借用したものだ。この記事にはCSSについての非常に有意義な内容なので、ぜひお読みになることをお勧めする。 プログラマーに幸あれ! 著者紹介Steve Stchur(Steve Stchur)
最新トップニュース
|
【ケータイ USA】新しい iPod は来週火曜に発表されるだろう(9月6日 13:00)
Apple が『iPod』関連の発表を準備中、内容は如何に(9月4日 12:40)
なぜ勝った? 世界No.1シェアをつかんだ“Windows”(9月5日 11:00)
【ケータイ USA】イギリスの団体が iPhone の広告における Apple の虚偽に言及(8月30日 13:00)
ソフトバンクモバイル、8月の純増数は約16万件――携帯電話契約数に関する速報(9月5日 14:40)
私の周りは“geek out”している人ばかり(9月5日)
|