「Ajax したい!」Web デザイナーのための Spry 集中講座
第二回:Spry を使ったプルダウンメニューの作成今月号の記事
- Java開発者も絶賛するActionScript 3、その魅力
- 「Ajaxしたい!」WebデザイナーのためのSpry集中講座
- 『北斗の拳』とブログの融合 ─ 「グルメの拳」
- the Edge Recommends! 最新サイトアイデア帳
- Edge 最新ニュース/イベント・セミナー情報
前回はXMLのデータをSpryで読み込み、データセットを作成してテーブルに表示するところまでご説明しました。今回はそのデータセットの機能を使ったプルダウンメニューの作成と、プルダウンメニューで選択した内容によって変化するフィルタ機能を作成します。少しだけJavaScriptの関数を作成する必要がありますが、まさにAjaxの醍醐味ともいうべき、優れたユーザインタフェイスが完成しますので、ぜひ挑戦してみてください。
前回の表示されたXMLのデータを見てみると、その中に共通のカテゴリが複数あることにお気づきでしょう。これを1つのメニューにまとめ、ユーザが選択できるようにしてテーブルの表示内容をすっきりさせましょう。
まずは、 ds_category という名前のデータセットを作成して、Product.xmlのXMLデータの中から Category ノードにある値だけを取得してみましょう。スクリプトタグの中に以下のような記述を追加してください。
<script type="text/javascript">
<!--
var dsPlist = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW");
dsPlist.setColumnType("@recordid", "number");
dsPlist.setColumnType("Price", "number");
var ds_category = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW/Category"); //新しく追加
//-->
</script>
次にこれを表示する<form>フィールドと<select>タグを記述します。以下の例では<form>フィールドをSpryの表示領域として定義し、<option>タグではCategoryノードの値をデータセットの行数分だけ繰り返して動的に表示させています。
<form name="CTform" spry:region="ds_category">
<select name="selectCategory">
<option spry:repeat="ds_category" value="{Category}">{Category}</option>
</select>
</form>
この5行だけで、右のようなカテゴリの値を表示するプルダウンメニューが完成です。
データのソートと重複の削除
しかし、まだCategoryノードの値をそのまま表示しているだけなので、データの並び順はXMLに記述された順ですし、同じ値も複数存在するためメニューとして使うにはまだまだ不適当です。Spryのデータセットでは、並び替え(Sort)や重複行の削除(Distinct)もコマンド指定だけで簡単に行えます。次はこれを利用して、不要な重複行を削除したメニュー用のデータセットに整形していきましょう。先ほど作成したデータセットに戻って、オプションパラメータとして以下を追加します。
<script type="text/javascript">
<!--
var dsPlist = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW");
dsPlist.setColumnType("@recordid", "number");
dsPlist.setColumnType("Price", "number");
var ds_category = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW/Category" ,{sortOnLoad:"Category",distinctOnLoad:true}); //新しく追加
//-->
</script>
sortOnLoad:"Category"でXMLが読み込まれる際にCategoryのデータをソートし、さらにdistinctOnLoad:trueとすることで重複するデータを削除しています。これによって表示は右のように変化します。これでかなりメニューらしくなりました。
フィルタリング
外部から飛んできた変数(パラメータ)によって内容を変化させるページ(マスター/詳細ページ)は、PHPや ColdFusion のようなスクリプトでは一般的によく使われる手法ですが、Spryでは複数の表示領域を設定することで同一のページ内であっても同様のページを作成できます。これは他のスクリプトよりも驚くほど簡単です。変数によってどのようにデータセットの値を変化させるかは様々な方法がありますが、ここではXpathの値を操作する手法をご紹介します。
まずは手始めに、Xpathの値にCategoryの値(ここでは'Web')を直接指定してテーブルの表示を変えてみましょう。
<script type="text/javascript">
<!--
var dsPlist = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW[Category = 'Web']");
dsPlist.setColumnType("@recordid", "number");
dsPlist.setColumnType("Price", "number");
var ds_category = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW/Category" ,{sortOnLoad:"Category",distinctOnLoad:true});
//-->
</script>
| ID | 製品 | 種別 | 価格 |
|---|---|---|---|
| {@recordid} | {Product} | {Category} | {Price}円 |
Categoryの値が’Web'のものだけを表示させています。このように、Xpathの後に角括弧([ ])で括ってノードの値を直接指定することでフィルタリングできます。
これを発展させて、プルダウンメニューの値が変わることによって呼ばれるJavaScriptの関数で、Xpathの値を変えてみましょう。先ほどフィルタリングしたXpathの設定を元に戻し、そのうえでスクリプトタグに以下の記述を加えます。
<script type="text/javascript">
<!--
var dsPlist = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW");
dsPlist.setColumnType("@recordid", "number");
dsPlist.setColumnType("Price", "number");
var CategoryFilter = function (category) { // 任意の関数を作成
var xpath = "PRODUCT_DATABASE/ROW"; // 変数xpath に初期値を設定
xpath += "[Category = '" + category + "']"; // xpathの値に関数のパラメータを追加
dsPlist.setXPath(xpath); // データセットにXpathを再設定
}
var ds_category = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW/Category" ,{sortOnLoad:"Category",distinctOnLoad:true});
//-->
</script>
新しく任意のJavaScript関数CategoryFilterを作成し、あらかじめパラメータとしてCategoryの値を受け渡せるようにします。次に、変数 xpath を用意して、その初期値としてXpathの値を設定しています。その次の行では、作成した変数 xpath の値にパラメータ Category の値を連結して、全体としてXpathの値がフィルタとして機能する形にしています。最後に、このXpathのフィルタをデータセットとして再設定し、フィルタを動作させます。
関数の準備が出来ましたので、それを呼び出す設定を<select>タグに追加します。
<form name="CTform" spry:region="ds_category">
<select name="selectCategory" onchange="CategoryFilter(this.value)">
<option spry:repeat="ds_category" value="{Category}">{Category}</option>
</select>
</form>
ユーザがメニューから値を選択すると関数CategoryFilterが呼び出され、ユーザが変更した値に応じてテーブルの内容が瞬時に変化します。
| ID | 製品 | 種別 | 価格 |
|---|---|---|---|
| {@recordid} | {Product} | {Category} | {Price}円 |
最後にメニューらしく、選んだフィルタの設定内容を解除する項目も作ってみました。コードは以下になります。
<script type="text/javascript">
<!--
var dsPlist = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW");
dsPlist.setColumnType("@recordid", "number");
dsPlist.setColumnType("Price", "number");
var CategoryFilter = function (category) {
var xpath = "PRODUCT_DATABASE/ROW"; if (category != "null"){
xpath += "[Category = '" + category + "']";
}
dsPlist.setXPath(xpath);
}
var ds_category = new Spry.Data.XMLDataSet("Product.xml", "PRODUCT_DATABASE/ROW/Category" ,{sortOnLoad:"Category",distinctOnLoad:true});
//-->
</script>
(中略)
<form name="CTform" spry:region="ds_category">
<select name="selectCategory" onchange="CategoryFilter(this.value)">
<option value="null" selected="selected">なし</option>
<option spry:repeat="ds_category" value="{Category}">{Category}</option>
</select>
</form>
| ID | 製品 | 種別 | 価格 |
|---|---|---|---|
| {@recordid} | {Product} | {Category} | {Price}円 |
Spryによるメニュー作成は、色々なアイデアによって多様な作成方法があります。まだ日本語化された資料が少ないためSpryそのものを扱うことに躊躇してしまうことも多いでしょうが、提供されているサンプルページはそんなアイデアの宝庫です。そららを参考にしつつ、まずは身近なものから、少しずつSpryを扱うことに挑戦してみて下さい。
