SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

DisplayTagとJavaScriptによる高機能なテーブルの作成

フリーのタグライブラリを使ってJSPのテーブル作成を効率化する

列の並べ替えと書式設定

 テーブル内の列を並べ替え可能にするには、その列にsortable属性を指定し、<display:column sortable="true">のようにします。これにより、列の見出しが、テーブルデータを昇順または降順に並べ替えるためのハイパーリンクになります。テーブルのHTMLが生成されるときには、列見出しのセルが、<th class="order1">(昇順の場合)または<th class="order2">(降順の場合)として出力されます。このクラス名に基づき、列見出しのCSS背景イメージとして上矢印または下矢印を追加することができます。

 既定では、現在表示されているページ上のデータだけが並べ替えられます(後述の「ページナビゲーション」を参照)。この動作を変更するには、「displaytag.properties」ファイルにsort.amount=listというプロパティを追加します。サンプルアプリケーションでは、実際にこの設定を採用しています。

 テーブルデータを書式設定するには、書式を適用したい列にformat="Pattern"という形式で属性を追加します。Patternの部分には、有効なjava.text.MessageFormatパターンを指定できます。例えば<display:column format="{0,date,short}">とすると、2003年11月1日という日付が「11/1/03」という書式で出力されます(実際の書式はロケール設定によって異なります)。

行のグループ化と小計の計算

 DisplayTagの大きな特徴の1つは、行のグループ化と小計の計算の機能を組み込みで備えていることです。例えば、数多くの注文の明細行をデータソースから取得し、その結果を表示したいとします。このような場合によく問題になるのが、同じ情報が繰り返し表示されることです。同じ注文を構成する連続した明細行では、同じ顧客名、注文番号、注文日などが繰り返されることになります。このような状態だと、どの明細行がどの注文に関連付けられているのかが判別しにくくなります。

 DisplayTagは、グループ属性を持つ列(例えば<display:column group="1">の列など)を調べ、そのいずれかの列に繰り返しデータが含まれている行をすべてグループ化します。今回のサンプルアプリケーションでは、Customer列をgroup="1"、Order Number列をgroup="2"、Order Date列をgroup="3"としているため、この3つの列の組み合わせによって行がグループ化されます(リスト1参照)。

 また、テーブルにTotalTableDecoratorというテーブル装飾を指定していることに注目してください。これにより、total属性を持つ列の値がグループごとに合計され、その合計値がグループの下に独立した行として表示されます。この小計行には、DisplayTagによってtotalというCSSクラスが与えられるため、このクラスを通じて特殊なスタイルを簡単に適用することができます。こうしたテーブル装飾を指定するには、<display:table decorator="org.displaytag.decorator.TotalTableDecorator">とします。また、列の小計を有効にするには<display:column total="true">とします。

ページナビゲーション

 DisplayTagでは、<display:table pagesize="16">のようにpagesize属性を指定することで、テーブルにページナビゲーションを追加することができます。ページナビゲーションの際に遭遇し得るさまざまな状況(例えばデータが1ページ分しかない場合や、複数ページあるうちの先頭、中間、最終ページを表示する場合など)に対処できるようにするために、DisplayTagでは、paging.banner.onepagepaging.banner.firstpaging.banner.fullのようなプロパティが用意されています(リスト3参照)。

 これらのプロパティの使い方を示すために、具体的な例を1つ紹介しておきます。

paging.banner.full=<div class="pagelinks" align="right"><a href={1}>
    <img src="images/first.gif"></a><a href={2}>
    <img src="images/prev.gif"></a>{0}<a href={3}>
    <img src="images/next.gif"></a><a href={4}>
    <img src="images/last.gif"></a></div>

 このやや複雑なプロパティは、すべてのページングリンクを表示するときに、図2のようなバナーを出力することをDisplayTagに指示しています。

図2 DisplayTagExのすべてのページングリンクを表示するページングバナー
図2 DisplayTagExのすべてのページングリンクを表示するページングバナー

 ここでは、<div>を使用することで、ページングバナーにpagelinksというCSSスタイルを割り当てています。{1}は、データの先頭ページへのリンクを表すプレースホルダです。ここでは、クリッカブルイメージのターゲットURLとして使用されています。{2}{3}{4}は、それぞれ前ページ、次ページ、最終ページについてのプレースホルダです。{0}は、一連の番号付きページへのリンクを出力する特殊なプレースホルダです。

Excel、PDFなどへのエクスポート

 DisplayTagで表現したテーブルのデータをCSV(Comma Separated Value)、XML、Excel、PDF、RTFにエクスポートするには、テーブル属性を1つ追加し、プロパティをいくつか設定し、それぞれのエクスポートタイプについて<span>スタイルを作成する必要があります。

 まず、テーブルにexport属性を追加すると、DisplayTagによってエクスポート用のバナーが表示されます。例えば、<display:table export="true">のようにします。

 ページナビゲーションのときと同様に、DisplayTagにはエクスポート関連のプロパティが数多く用意されています。既定のプロパティは「displaytag.properties」ファイルで設定します。サポートされているすべての形式をユーザーが使用できるようにする場合は、通常はexport.bannerプロパティとexport.format.filenameプロパティを設定します。

 例えば、今回のサンプルアプリケーションでは、エクスポート形式のリスト(エクスポートバナー)を右端に配置し、このリストにpagelinksというCSSクラスを適用したいので、「displaytag.properties」ファイルに次のように記述しています(リスト3参照)。

export.banner=<div class="pagelinks" align="right">{0}</div>

 この設定だけを見ると少々分かりにくいのですが、エクスポートバナーが描画されるときには、個々のエクスポート形式のハイパーリンクが「export format」クラスの<span>スタイル(例えば<span class="export excel">など)の中に挿入されます。そのため、サンプルアプリケーションでは、それぞれの形式に対応するCSSクラスを次のような形で用意しています。

span.excel {
      background-image: url(../images/ico_file_excel.png);
      background-repeat: no-repeat;
      width: 16px;
}

 エクスポートしたデータのファイル名を設定するには、export.format.filenameプロパティをexport.pdf.filename=data.pdfのように指定します。

Javascriptによる行操作

 今回のサンプルアプリケーションのもう1つの要件は、ユーザーが行をマウスポインタで指すとその行が強調表示され、行のどこかをクリックすると、その行についての識別情報を含んだ新しい要求が生成されるようにすることです。この要件を満たすには、何らかのJavaScriptを取り入れる必要があります。

 サンプルアプリケーションでは、「RowHandlers.js」というJavaScriptファイルを用意し(リスト4参照)、その中にaddRowHandlers()という関数を作成しました。この関数は、HTMLテーブル内の各行に次の3つのイベントハンドラを追加します。

  1. onmouseover ―― 行のクラス属性を保存し、別の背景色または画像を持つ新しいスタイルへと変更します。
  2. onmouseout ―― 以前のクラス属性を復元します。
  3. onclick ―― 指定のURLにジャンプします。このとき、選択されたテーブル行に関する要求パラメータをURLに付加します。
リスト4 Rowhandlers.js
// Adds onmouseover, onmouseout, and onclick handlers
// to each table row.
// The onmouseover handler changes the row's class attribute to
// rowMouseOver.  The onmouseout handler changes it back.
// The onclick function makes a request for the specified url,
// including the innerHTML of the specified column
// as a request parameter.
function addRowHandlers(tableId, rowClassName, url,
    paramName, columnIndex) {
    var previousClass = null;
    var table = document.getElementById(tableId);
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        rows[i].onmouseover = function () {
            previousClass = this.className;
            this.className = this.className + " " + rowClassName ;
        };

        rows[i].onmouseout = function () {
            this.className = previousClass;
        };

        rows[i].onclick = function () {
            var cell = this.getElementsByTagName("td")[columnIndex];
            var paramValue = cell.innerHTML;
            location.href = url + "?" + paramName + "=" + paramValue;
        };
    }
}

 この「RowHandlers.js」を自作のJSPで利用するには、次のようにします。

  1. <head>セクション内でこのスクリプトにリンクします。
  2. <script src="js/RowHandlers.js" language="javascript"
        type="text/javascript" /></script>
    
  3. <body>タグのonload属性でaddRowHandlers()を呼び出します。
  4. <body onload= "addRowHandlers('row', 'rowMouseOver',
     'OrderDetail.jsp', 'id', 0)">
    

 手順2のタグの意味を解釈してみましょう。まず、ページの<body>セクションがロードされるときに、rowというidを持つテーブルに対してaddRowHandlers()関数が呼び出され、この関数によってテーブルの各行に3つのハンドラが追加されます。これらのハンドラが適用された場合、ユーザーがいずれかの行をマウスポインタで指すと、その行のCSSクラス属性がrowMouseOverに変更されます。マウスポインタが行から外れると、CSSクラス属性は元の値に戻ります。ユーザーが行をクリックすると「OrderDetail.jsp」が呼び出されますが、この呼び出し要求にはパラメータidの値が付加されます(この値は、クリックされた行の列0から取得されます)。

 サンプルアプリケーションでは、「OrderDetails.jsp」(リスト1参照)が前述の「RowHandlers.js」を使用しています。また、「OrderDetails.jsp」では、行IDの値を非表示の列に配置するという手法を使っています。この列を非表示にするために、<display:column>classおよびheaderClass属性をhiddenに設定しています(hiddenは、displayプロパティがnoneに設定されているCSSスタイルです)。これは、要求スコープで使用するデータをユーザーの目から隠したいときに役立つ、単純ながら効果的な方法です。

 DisplayTagは、JSP内にテーブルデータを簡単に表示したいときに役立つオープンソースのタグライブラリです。このライブラリは幅広い用途に利用でき、例えば検索アプリケーションでは検索結果を特定の列で並べ替え、そこから製品リストにジャンプさせるページナビゲーションを実現できますし、財務レポートアプリケーションでは数値の書式設定、グループ集計、PDFへのエクスポートの機能を利用できます。可能性は無限にあり、おそらく読者の皆さんが開発しているWebアプリケーションでも、DisplayTagがお役に立つでしょう。

 まずサンプルアプリケーションをダウンロードし、実際に試してみてください。その後、「OrderDetails.jsp」をテンプレートとして使い、目的に合ったダイナミックテーブルを作成してみましょう。ダウンロードサンプルに収録されているCSSファイル、JavaScriptファイル、プロパティファイル、画像ファイルは、そのままの形で利用しても、個々のアプリケーションに合わせて必要に応じて改変してもかまいません。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Stephen Strenn(Stephen Strenn)

カリフォルニア大学デービス校で電子工学の修士号を取得。Cogito Research Groupの主任調査員であり、赤外線検出器企業のコンサルタントを務める。進化計算、人工知能、ロボット工学の分野でいくつかの著作を発表。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/362 2006/08/22 15:45

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー