従来のページングは、開発者たちが動的 Web アプリケーションをビルドし始めた頃から使用されています。大規模なデータ・セットを表示するときには、常にページングによってデータのサブセットが一度に 1 つずつユーザーに表示されます。そしてユーザーは、Next ボタンや Previous ボタンを使ってデータ・セット (ページ) 間をナビゲートするのです。
現在、従来のページングのいくつかのバリエーションが使用されています。ユーザーに First、Previous、Next、そして Last ボタンを表示するものもあれば、番号を用いているものもあります。あるいは、この 2 つの方法を組み合わせる場合もあります。ページングのコンセプトは、ユーザーとサーバーの両方にとって大量のデータ・セットを効率的に扱うのに役立っています。
その一方で、開発者が Web アプリケーションを設計してビルドする方法は最近の Ajax 人気によって変わってきています。Ajax では、外観も振る舞いも従来のデスクトップ・アプリケーションに一層近い Web アプリケーションをビルドできます。さらに、すぐに使えるウィジェットが用意されたオープン・ソースや商用の JavaScript/Ajax フレームワークおよびライブラリーもいくつかあり、Ajax モデルを一層実装しやすくしています。これらのウィジェットを使えば、開発者は豊富なフィーチャーと機能を Web アプリケーションに難なく追加できます。
そんなフレームワークの 1 つが、Rico です。この記事では、このオープン・ソースのクライアント・サイド JavaScript フレームワークを簡単に紹介した後、Rico が提供するウィジェットの 1 つ、LiveGrid に焦点を当てます。この記事で実演してみるように、LiveGrid は従来のページング・モデルに置き換わるものとして Web アプリケーションに実装することができます。
Rico ライブラリーは、Web ページに一連の豊富な機能とウィジェットへのアクセスを提供するために、あらゆる Web ページに組み込むことのできる JavaScript ファイルです。ブラウザー間の互換性をはじめ、数々の複雑な実装の詳細はこのライブラリーが処理してくれるので、開発者はページの機能を作成することに専念できます。
Rico の機能またはウィジェットを利用する方法は極めて簡単です。数行のコードを書き込むだけで、特定のページに該当する機能またはウィジェットを組み込むことができるのです。例えば、Rico では非常に単純なインターフェースで Ajax サポートを Web ページに追加することができます。Ajax の機能を Web ページに追加するのに必要なのは、わずか 5、6 行の JavaScript コードだけで、このコードを書き込めば、XmlHttpRequest JavaScript オブジェクトを直接処理しなくても、サーバーへの Ajax 要求とサーバーからの応答を処理することができます。
ドラッグ・アンド・ドロップなどの視覚効果も、Rico ではごく簡単に Web ページに追加できます。Rico ライブラリーでは、あらゆる HTML オブジェクトや JavaScript オブジェクトをドラッグ可能オブジェクト、またはドロップ・ゾーンとして定義できます。いったん定義すれば、ドラッグ可能オブジェクトをページのあちこちにドラッグしたり、1 つ以上のユーザー定義ドロップ・ゾーンにドロップできるようになります。この機能の実装の詳細はすべて Rico が処理するため、開発者に必要なのは数行のコードを書き込むことだけです。
フェード・インやフェード・アウト、動画化したサイズ変更や配置、そして回転する形状などの映画のような効果を追加するのも、Rico にはお手の物です。最も人気のある Rico ウィジェットの 1 つとして挙げられる Accordion では、一連の縮小可能ドロワーを表示します。ドロワーごとにドロワー・ヘディングとコンテンツ領域があり、ドロワー・ヘディングをクリックすると、そのドロワーのコンテンツが表示され、残りのドロワーのコンテンツが非表示になります。また、非常に人気の高いウィジェットには LiveGrid もあります。この記事の残りの部分では、このウィジェットに話題を絞ります。
図 1 の LiveGrid はスクロール可能な情報テーブルです。テーブル内のデータは、ユーザーがスクロール・バーをクリックするたびに即時更新されます。このテーブルは実データ・ソースに接続されていて、テーブルの更新は Ajax を活用して行われます。
図 1. 初期状態の LiveGrid
この LiveGrid は 20 本の映画をスクロール可能リストに表示し、ユーザーがスクロール・バーをクリックするたびにテーブルのコンテンツが新しい映画のセットで更新されます。新しいデータのセットが必要になり次第、Rico はサーバーに対して Ajax コールを行います。Rico ではパフォーマンスの向上、さらにスクロールのスムーズな動作のためにバッファリングを使用しています。つまり、スクロール・バーをクリックするごとに毎回 Ajax 要求が行われるわけではありません。Rico はまずバッファーにあるデータを使用してグリッドを更新し、バッファーのデータをすべて使い切った時点で、データを追加するために Ajax 要求を行います。図 2 は、ユーザーがスクロール・バーを 1 回クリックした後の LiveGrid です。LiveGrid は列によるソートもサポートするので、ソートがグリッドに実装されていれば、ユーザーが列名をクリックするとその列を基準にデータがソートされます。
図 2. スクロール・バーを 1 回クリックした後の LiveGrid
実地の例として、上記の Movies LiveGrid を作成する方法を紹介します。Rico ホーム・ページから rico.js と prototype.js をまだダウンロードしていない場合は、ダウンロードしてください。Rico ライブラリーは Prototype という別のオープン・ソース・フレームワークの機能を使用するため、prototype.js が必要なことに注意してください。また、Rico からの Ajax 呼び出しを処理する Web/アプリケーション・サーバーも必要です。この例では、Apache Tomcat 6.0 を使用します。
まず、この例のクライアント・サイド・コードを作成するところから始めます。何もないページから始めてください。最初に必要な作業は、rico.js ライブラリーと prototype.js ライブラリーをページに組み込むことです。この 2 つのライブラリー・ファイルが HTML ファイルと同じディレクトリー内にあるとすると、ライブラリーをページに組み込むためのコードはリスト 1 のようになります。
リスト 1. Rico および Prototype ライブラリーからの作業開始
<script src="prototype.js"></script>
<script src="rico.js"></script>
|
図 1 のテキスト「Showing 1 - 5 of 20 Movies」を表示するラベルのプレースホルダーを追加します。このラベルは、ユーザーがスクロール・バーをクリックするたびに更新されます。
リスト 2. showLabel の設定
<div id="showingLabel" >Showing 1 - 5 of 20 Movies</div> |
次に、図 1 の列名 (Number、Title、Year など) を表示する LiveGrid ヘッダーを追加します
リスト 3. LiveGrid ヘッダーの追加
<table cellspacing="0" cellpadding="0" width="400">
<tr>
<th bgcolor="#999999" width="30">#</th>
<th bgcolor="#999999" width="310">Title</th>
<th bgcolor="#999999" width="60">Year</th>
</tr>
</table>
|
これで、Rico が映画のデータを表示するためのテーブルの作成に取り掛かれます。以下のコードで作成するテーブルには、6 つの行と 3 つの列があります。テーブル内の行の背景は 1 行おきに明るいグレーになります。LiveGrid が正しく機能するためには必ず、テーブル内にもう 1 つ余分な行が必要です。つまり、LiveGrid を 5 行にするには、作成する HTML テーブルに必要な行は 6 行ということです。この余分な 1 行がないと、LiveGrid のスクロール機能が正しく動作しません。リスト 4 に、LiveGrid が使用する HTML テーブルを作成するためのコードを示します。
リスト 4. LiveGrid データの HTML テーブル
<div id="movieDiv" style="float:left">
<table id="movie_grid" cellspacing="0" cellpadding="0"
width = "400px" style="border:1px solid #ababab" >
<tr>
<td width="30"> </td>
<td width="310"> </td>
<td width="60"> </td>
</tr>
<tr>
<td bgcolor="#eeeeee" width="30"> </td>
<td bgcolor="#eeeeee" width="310"> </td>
<td bgcolor="#eeeeee" width="60"> </td>
</tr>
<tr>
<td width="30"> </td>
<td width="310"> </td>
<td width="60"> </td>
</tr>
<tr>
<td bgcolor="#eeeeee" width="30"> </td>
<td bgcolor="#eeeeee" width="310"> </td>
<td bgcolor="#eeeeee" width="60"> </td>
</tr>
<tr>
<td width="30"> </td>
<td width="310"> </td>
<td width="60"> </td>
</tr>
<tr>
<td bgcolor="#eeeeee" width="30"> </td>
<td bgcolor="#eeeeee" width="310"> </td>
<td bgcolor="#eeeeee" width="60"> </td>
</tr>
</table>
</div>
|
テーブルとデータがセットアップできたら、次に、リスト 4 の HTML テーブルを Rico LiveGrid に変換する JavaScript 関数を定義します。リスト 5 に示すこの関数は、loadGrid 関数と呼ばれます。
リスト 5. Rico LiveGrid の定義
<script>
function loadGrid() {
var opts = { prefetchBuffer: true, onscroll : updateLabel };
var liveGrid = new Rico.LiveGrid( 'movie_grid',5, 20, 'MovieData', opts);
}
</script>
|
loadGrid 関数の最初の行では、LiveGrid のオプションを指定します。prefetchBuffer オプションを true に設定すると、Rico は LiveGrid の作成中にデータをフェッチします。このオプションを false に設定した場合は、ロードされた時点での LiveGrid にはデータがありません。スクロール・バーがクリックされなければ、データは表示されないことになります。
onScroll オプションを使用して、ユーザーがスクロール・バーをクリックするたびに Rico がコールする関数を定義できます。上記の例では、ラベル「Showing 1 - 5 of 20 Movies」を更新しなければなりません。そのため、updateLabel という JavaScript 関数を定義して、ユーザーがスクロール・バーをクリックするたびに Rico がこの関数をコールするようにしています。この例では使用していませんが、onscrollidle オプションを使用すると、スクロール操作が休止または停止したときに JavaScript 関数をコールすることができます。
その他の便利なオプションには、requestParameters もあります。このオプションでは、Ajax 要求を処理するサービスに追加パラメーターを送信できます。また、requestParameters を使用して LiveGrid に表示するデータをフィルタリングすることも可能です。例えば LiveGrid にアクション映画だけを表示させたい場合、requestParameters を genre=action に設定すると、Ajax コールを処理するサービスはこのジャンルと一致する映画だけを返します。
loadGrid 関数の 2 行目では、実際に LiveGrid を宣言します。コンストラクターの最初のパラメーターは、LiveGrid に変換される HTML テーブルの ID です。この例の場合、ID は「movie_grid」となっています。2 番目のパラメーターは LiveGrid に表示する行数 (この例では 5 行)、3 番目のパラメーターは LiveGrid の最大行数 (この例では 20 行) を指定します。4 番目のパラメーターは、Ajax コールを処理するサーバー・サイド・スクリプト/サーブレットの URL です。この例のために、Rico からの Ajax 要求を処理するサーブレットとして私が作成したのは、MovieData という名前のサーブレットです。これについては、後で詳しく説明します。最後のパラメーターは関数の 1 行目で宣言した変数で、この変数がリスト 5 に示した LiveGrid のオプションを定義します。
HTML ページがロードされるときには常に、loadGrid 関数がコールされなければなりません。リスト 6 に、その方法を示します。
リスト 6. loadGrid のコール
<body onload="javascript:loadGrid()"> |
最後に定義するのは、Movie LiveGrid の上にあるラベルを更新する関数です。リスト 7 のように定義します。
リスト 7. updateLabel 関数
<script>
function updateLabel( liveGrid, offset ) {
$('showingLabel').innerHTML = "Showing " + (offset+1) + " - " +
(offset+liveGrid.metaData.getPageSize()) + " of " +
liveGrid.metaData.getTotalRows() + " movies";
}
</script>
|
updateLabel 関数は、ユーザーがスクロール・バーをクリックするたびにコールされます。この関数は基本的に Rico ライブラリーにある変数を使って「Showing 1 - 5 of 20 movies」のようなストリングを作成します。Prototype JavaScript フレームワークを使い慣れていない場合は、$(DIVNAME) 構文を使用して、ID が DIVNAME と一致するページ上にあるオブジェクトを参照することもできます。つまり、$('showingLabel').innerHTML は document.getElementById("showingLabel").innerHTML と同じことです。この例では、DIV タグの innerHTML 値を、ユーザーがスクロール・バーをクリックするたびに更新されるストリングと置き換えています。
Rico におけるコーディングの大半はクライアント・サイドで行いますが、肝心な作業のいくつかはサーバー・サイドで行います。すなわち、Ajax コールを処理するためにサーバー・サイド・スクリプトまたはサーブレットをセットアップする必要があります。前述したように、私は Rico からの Ajax 要求を処理するサンプル・サーブレットを作成しました。リスト 8 に、LiveGrid ウィジェットと正しく連動するために必要なサーブレットからの XML 応答を示します。LiveGrid が機能するには、XML 応答は以下のフォーマットでなければなりません。
リスト 8. XML 応答の必須フォーマット
<?xml version="1.0" encoding="ISO-8859-1"?>
<ajax-response>
<response type="object" id='movie_grid_updater'>
<rows update_ui='true' >
<tr>
<td>1</td>
<td>Star Wars</td>
<td>1977</td>
</tr>
<tr>
<td>2</td>
<td >The Godfather</td>
<td>1972</td>
</tr>
...
</rows>
</response>
</ajax-response>
|
注目すべき点は、response タグに含まれる id 属性の最初の 2 つの単語 (movie_grid) が、先ほど LiveGrid に定義した HTML テーブルの id 属性と同じであるということです。Rico が LiveGrid 内のデータを更新するには、この 2 つの id 属性が一致していなければなりません。通常、サーバー・サイド・スクリプトまたはサーブレットはデータ・ソースに接続し、上記のフォーマットで XML を生成します。Rico はこの XML 応答からデータを抽出し、抽出した新しいデータを LiveGrid に入力するプロセスを処理します。そのため、応答のコンテンツ・タイプは "text/xml" に設定することが重要となります。このように設定しないと、LiveGrid は機能しません。また、XML バージョンとエンコード方式も、それぞれ "1.0" および "ISO-8859-1" に設定する必要があります。Java™ コードでは、リスト 9 のようにコンテンツ・タイプを設定することができます。
リスト 9. Ajax 応答のコンテンツ・タイプの設定
response.setHeader("Content-Type", "text/xml");
|
ここで、スクリプトやサーブレットがどのデータ・セットをいつ生成するのかをどうやって認識するのか、疑問に思うかもしれません。この記事の最初のほうで、Rico フレームワークはバッファリングを使用して、必要になり次第データを要求すると説明しました。Rico がバックエンドに対して Ajax 要求を行うときには、最大 4 つのパラメーターを URL 内のクエリー・ストリングとして送信できます。バックエンドは正しい Ajax 応答を生成するため、使用可能であれば 4 つすべてのパラメーターを使用します。この 4 つのパラメーターとは、以下のとおりです。
- offset
- 返してほしいデータのデータ・セット内での最初の行を指定します。一例として、LiveGrid が最初にロードされたときのオフセットがゼロだとします。Rico は初期ロード中に 150 行のデータをフェッチし、バッファリングを使用してデータを保管しました。Rico はこの 150 行すべてを表示すると、新しいデータを取得するためにオフセットの値を 151 に設定してバックエンドに対して Ajax 要求を行います。
- page_size
- Rico がバックエンドに対して返してほしいデータの行数を指定します。
- sort_col
- このパラメーターが示す列を基準にデータをソートしてから、Rico にデータを送ります。
- sort_dir
- 列のソートを昇順で行うか、降順で行うかを指定します (ACS または DECS)。
上記のコードをすべて作成すると、ブラウザーで HTML ページを指定して実際の LiveGrid を表示させることができます。
Rico はオープン・ソースの JavaScript ライブラリーで、ユーザーに豊富な機能を提供するために Web アプリケーションで使用できます。この記事ではRico の主要なポイントを説明し、LiveGrid ウィジェットを紹介しました。また実用的な例を用いて、Web アプリケーションで従来のページングを LiveGrid ウィジェットに置き換える方法を示しました。
学ぶために
-
Ajax resource center: developerWorks にある Ajax 関連の豊富な記事、チュートリアル、そして Web チャットを紹介しています。
-
「Discover the Ajax Toolkit Framework for Eclipse」(Tim McIntire 著、developerWorks、2006年11月): Dojo、Zimbra、Rico などのオープン・ソース Ajax ツール・キットのサポートを追加して、Eclipse Web Tools Platform を拡張してください。
-
「Ajax for Java developers: Build dynamic Java applications」(Philip McCarthy 著、developerWorks、2005年9月): 従来の Web ページング・モデルの枠を超えた Ajax のナビゲート方法を説明しています。
-
Open Rico Demos ページ: Rico ライブラリーの機能とウィジェットを調べてみてください。
-
公式 Rico LiveGrid tutorial: Rico ライブラリーの作成者たちによるチュートリアルを調べてみてください。
-
JavaScript Multipurpose Frameworks: 他の JavaScript フレームワークについて学んでください。
-
テクノロジーのブックストア: この技術やその他の技術に関する本を参照してください。
-
developerWorks Web development ゾーン: Web 技術を専門とした記事およびチュートリアルで、サイト開発の技術を磨いてください。
-
developerWorks technical events and webcasts: 学習の早道となり、難しいソフトウェア・プロジェクトの品質とその結果を改善する技術的セッションが満載です。
製品や技術を入手するために
-
Rico ライブラリー: Open Rico ホーム・ページからダウンロードしてください。
-
Prototype ライブラリー: Rico ライブラリーに追加しなければならないライブラリーです。
-
developerWorks の Web Development Downloads and products エリア: Web 開発に関連するダウンロードとその他の資料を見つけてください。
-
IBM トライアル・ソフトウェア: developerWorks から直接ダウンロードできるソフトウェアで、次の開発プロジェクトを構築してください。
議論するために
-
developerWorks blogs: developerWorks コミュニティーに参加してください。
