はじめに
もしあなたがWebアプリケーション開発者ならば、データをテーブルとして表示するための作業を毎日行っていることでしょう。本稿では、DisplayTagライブラリと簡単なJavaScriptを使用して、さまざまな機能を備えたJSPページ用のテーブルを短時間で作成する方法を紹介します。具体的には、次のような機能を持ったテーブルを作成します。
- 1行ごとに異なる背景色
- 列の並べ替えと書式設定
- 行のグループ化と小計の計算
- ページナビゲーション
- XML、Excel、PDF、CSVへのエクスポート
- 標準JSPおよびEL(Expression Language)のサポート
- 行のインタラクティブ操作――ユーザーがいずれかの行をマウスポインタで指すと、その行が強調表示される。ユーザーが行のどこかをクリックすると、その行についての識別情報を含んだ新しい要求が生成される。
本稿では、いくつもの注文の明細行を表示するDisplayTagExというサンプルアプリケーションを紹介します。まずはDisplayTagExのライブデモを見てください(画面例は図1を参照)。DisplayTagExアプリケーションでは、1つ1つの注文ごとに明細行をグループ化し、各グループの小計を示します。ユーザーが行のどこかをクリックすると、選択した項目に関する詳細情報のページにジャンプします。リスト1とリスト2に、それぞれ「OrderDetails.jsp」と「displaytagex.css」のソースを示します。
<display:table name="\${orderDetails}" export="true" id="row" class="dataTable" defaultsort="1" defaultorder="ascending" pagesize="16" cellspacing="0" decorator="org.displaytag.decorator.TotalTableDecorator"> <display:column property="id" title="ID" class="hidden" headerClass="hidden" media="html" /> <display:column property="customerName" title="Customer" sortable="true" group="1" class="customer" headerClass="customer" /> <display:column property="orderNumber" title="Order Number" sortable="true" group="2" class="orderNumber" headerClass="orderNumber" /> <display:column property="orderDate" title="Order Date" sortable="true" format="{0,date,short}" group="3" class="orderDate" headerClass="orderDate" /> <display:column property="productName" title="Product" sortable="true" class="productName" /> <display:column property="quantity" title="Quantity" sortable="true" class="quantity" headerClass="quantity" /> <display:column property="total" title="Line Item Total" sortable="true" format="{0,number, currency}" total="true" class="lineItemTotal" headerClass="lineItemTotal" /> </display:table>
.dataTable {
background-color: white;
border: 1px solid #000066;
font-size : 9pt;
margin: 5px;
width:100%;
}
.dataTable th {
border-right: 1px solid #c8c8ff;
padding-left: 2px;
padding-right:12px;
font-family: arial, helvetica, sans-serif;
font-weight: bold;
color: white;
background-color: #000066;
margin-right: 10px;
white-space: nowrap;
}
.dataTable td {
font-family: verdana, arial, helvetica, sans-serif;
padding-left: 2px;
}
.dataTable tr.total td {
white-space: nowrap;
vertical-align: top;
font-weight: bold;
border-top: 1px solid black;
padding-bottom: 10px;
}
.dataTable tr.total td.customer {
visibility: hidden;
}
.dataTable td.hidden {
display: none;
}
.dataTable th.hidden {
display: none;
}
.dataTable th.r {
text-align: right;
padding-right: 10px;
}
.dataTable th.c {
text-align: center;
}
.dataTable td.r {
text-align: right;
padding-right: 10px;
}
.dataTable td.c {
text-align: center;
}
.dataTable tr.odd {
background-color: whitesmoke;
}
.dataTable tr.even {
background-color: #d6cfe6;
}
.dataTable th a ,.dataTable th a:visited {
text-align: left;
color: white;
}
.dataTable th a:hover {
color: #ffcc00;
background-color: transparent;
}
.dataTable .order1 {
background-position: right;
background-image: url(../images/arrow_up.gif);
background-repeat: no-repeat;
}
.dataTable .order2 {
background-position: right;
background-image: url(../images/arrow_down.gif);
background-repeat: no-repeat;
}
.pagelinks {
color: #999999;
margin: 5px;
}
.pagelinks img {
vertical-align: middle;
}
span.export {
padding: 0 4px 1px 20px;
font-size: x-small;
text-align: center;
}
span.excel {
background-image: url(../images/ico_file_excel.png);
background-repeat: no-repeat;
width: 16px;
}
span.csv {
background-image: url(../images/ico_file_csv.png);
background-repeat: no-repeat;
width: 16px;
}
span.xml {
background-image: url(../images/ico_file_xml.png);
background-repeat: no-repeat;
width: 16px;
}
span.pdf {
background-image: url(../images/ico_file_pdf.png);
background-repeat: no-repeat;
width: 16px;
}
span.rtf {
background-image: url(../images/ico_file_rtf.png);
background-repeat: no-repeat;
width: 16px;
}
.dataTable tr.rowMouseOver {
background-image: url(../images/selected.gif);
background-repeat: repeat-x;
background-color: #ffff99;
}
html,body {
width: 100%;
height: 100%;
margin: 0px;
font-family: arial, helvetica, sans-serif;
font-size: 9pt;
}
.pageHeader {
height: 60px;
background-image: url(../images/header.gif);
background-repeat: repeat-x;
}
.pageHeaderText {
font-size: 30px;
margin-left: 5px;
color: whitesmoke;
font-family: "century gothic", verdana, arial, helvetica,
sans-serif;
font-weight: bold;
text-align: left;
display:inline;
white-space: nowrap;
}
.leftMenu {
white-space: nowrap;
height: 100%;
background-color: #d6cfe6;
font-family: verdana, arial, helvetica, sans-serif;
}
.content {
width: 100%;
padding: 10px;
}
.rightColumn {
width: 3px;
}
.customer {
width: 20%;
text-align: left;
}
.orderNumber {
width: 10%;
text-align: left;
}
.orderDate {
text-align: center;
width: 10%;
}
.productName {
width: 25%;
}
.quantity {
text-align: center;
width: 10%;
}
.lineItemTotal {
text-align: right;
width: 15%;
padding-right:10px;
}
.logo {
border-top: 1px solid #000066;
border-left: 1px solid #000066;
border-bottom: 1px solid #000066;
display:inline;
text-align: right;
}
.code {
font-family: verdana, arial, helvetica, "courier new", monospace;
font-size: 9pt;
}
.borderedInline {
display: inline;
border: 1px solid black;
}
a:link {
color: #000099;
text-decoration: none;
background-color: transparent;
font-weight: bold;
}
a:visited {
color: #000099;
text-decoration: none;
background-color: transparent;
font-weight: bold;
}
a:hover {
color: #d68000;
background-color: transparent;
font-weight: bold;
}
img {
border: 0px;
}
本稿のサンプルアプリケーションの開発および配置に使用した環境は、DisplayTagライブラリv1.1、JDK 5.0、MyEclipse 4.1、Tomcat 5.5です。ただし、ここで紹介した手順は、JSPを使ったWebアプリケーション開発の現場ならば、どんな環境でも応用できます。


sans-serif;
font-weight: bold;
text-align: left;
display:inline;
white-space: nowrap;
}
.leftMenu {
white-space: nowrap;
height: 100%;
background-color: #d6cfe6;
font-family: verdana, arial, helvetica, sans-serif;
}
.content {
width: 100%;
padding: 10px;
}
.rightColumn {
width: 3px;
}
.customer {
width: 20%;
text-align: left;
}
.orderNumber {
width: 10%;
text-align: left;
}
.orderDate {
text-align: center;
width: 10%;
}
.productName {
width: 25%;
}
.quantity {
text-align: center;
width: 10%;
}
.lineItemTotal {
text-align: right;
width: 15%;
padding-right:10px;
}
.logo {
border-top: 1px solid #000066;
border-left: 1px solid #000066;
border-bottom: 1px solid #000066;
display:inline;
text-align: right;
}
.code {
font-family: verdana, arial, helvetica, "courier new", monospace;
font-size: 9pt;
}
.borderedInline {
display: inline;
border: 1px solid black;
}
a:link {
color: #000099;
text-decoration: none;
background-color: transparent;
font-weight: bold;
}
a:visited {
color: #000099;
text-decoration: none;
background-color: transparent;
font-weight: bold;
}
a:hover {
color: #d68000;
background-color: transparent;
font-weight: bold;
}
img {
border: 0px;
}