データを並べ替える
では、<grid>で表示した項目に、列幅の調整と行の並べ替え機能を追加してみましょう。
<?page title="Index Page"?> <zk> <zscript> class GridComparator implements Comparator { boolean asc; public GridComparator(boolean ascending) { asc = ascending; } public int compare(Object o1, Object o2) { Row r1 = (Row)o1; Row r2 = (Row)o2; return 1; } } Comparator asc = new GridComparator(true); Comparator dsc = new GridComparator(false); </zscript> <window title="Welcome to ZK!" border="normal" width="500px"> <label>※入力フォームのレイアウト</label> <separator /> <grid width="90%"> <columns sizable="true"> <column label="名前" sortAscending="${asc}" sortDescending="${dsc}" /> <column label="メールアドレス" sortAscending="${asc}" sortDescending="${dsc}" /> <column label="電話番号" sortAscending="${asc}" sortDescending="${dsc}" /> </columns> <rows> <row> <label>つやの</label> <label>tuyano@mac.com</label> <label>090-9999-9999</label> </row> <row> <label>やまだたろう</label> <label>taro@yamada.com</label> <label>080-8888-8888</label> </row> <row> <label>田中花子</label> <label>hanako@tanaka.com</label> <label>070-7777-7777</label> </row> </rows> </grid> <separator /><separator /> </window> </zk>
ヘッダーとヘッダーの境界部分をマウスでドラッグすると、それぞれの列幅を調整できます。また、各列のヘッダーをクリックすると、その列の値を基準にデータを並べ替えることができます。1度クリックすると昇順に、さらにもう1度クリックすると降順になります。
まず列幅の調整からです。これは非常に簡単で、<columns>タグにsizable="true"という属性を追加するだけです。問題は、並び順の調整です。これは、各<column>に「sortAscending」「sortDescending」といった属性を用意します。これらには、sortAscending="${asc}" sortDescending="${dsc}"というように値が設定されています。この${○○}という書き方は、JSPで見覚えがあると思いますが、式言語(Expression Language)です。ZULファイルでは、このJSPの式言語と同じ書き方で変数を埋めこむことが可能なのです。
ここでsortAscending/sortDescendingに式言語を使って指定しているのは、「Comparator」のインスタンスです。Comparatorというのは、Javaプログラマならば、オブジェクトの並び替えを行うの用いられるインターフェイスであることは知っていると思います。ソートのためのComparatorクラスを用意し、これをsortAscending/sortDescending属性に設定することでソートが可能となります。
ここでは、GridComparatorというクラスを定義し、そのインスタンスを使っています。一応、昇順と降順での違いを処理できるようにascという真偽値のフィールドを用意してあります(ここでは特に使っていません)。compareメソッドでは2つのObjectが渡されますが、これは<grid>の列の並べ替えでは「Row」というクラスのインスタンスとして渡されます。ここでは、単純に1を返しているだけですが、昇順降順や列に応じて並び順のチェックを変更することもできます。
なお、今回は、<window>タグの手前に<zscript>タグを置いています。そのため、まず<zk>というタグをルートに用意し、その中に<zscript>と<window>を用意してあります。ページ内に<window>が1つあるだけというシンプルな構造なら<window>がルートで良いのですが、そうでない場合には、このように<zk>タグから始めるのが良いでしょう。
繰り返しタグによる表示の作成
この<grid>による表の作成は、多数のデータを利用する代表的なコンポーネントといって良いでしょう。もう少し「データを表示する」ということについて、この<grid>を使って掘り下げてみましょう。
先の例では、表示するすべてをタグとして記述していました。しかし、このやり方では、データと表示をうまく切り分けることができません。こうしたコンポーネントでは、データはデータでまとめて管理したいものです。
データを配列などの形でまとめておき、そこから繰り返し値を取り出して表示していく、というようなやり方ができれば、データの管理は楽になります。これは、ZUMLに用意されている繰り返しのための属性を利用することで可能となります。
<?page title="Index Page"?> <zk> <zscript> String[][] datas = new String[][]{ new String[]{"一郎","one@1.com","111-1111"}, new String[]{"次郎","two@2.com","222-2222"}, new String[]{"三朗","three@3.com","333-3333"}}; </zscript> <window title="Welcome to ZK!" border="normal" width="500px"> <label>※入力フォームのレイアウト</label> <separator /> <grid width="90%"> <columns sizable="true"> <column label="名前" /> <column label="メールアドレス" /> <column label="電話番号" /> </columns> <rows> <row forEach="${datas}"> <label>${each[0]}</label> <label>${each[1]}</label> <label>${each[2]}</label> </row> </rows> </grid> <separator /><separator /> </window> </zk>
ここでは、表示するデータはdatasという2次元配列にまとめられています。ここから順に要素を取り出し、それを各行に表示していくわけです。しかし、<rows>内には1つの<row>タグしかありません。ここでは、<row>タグ内に「forEach="${datas}"」という属性が指定されています。このforEachが、今回のポイントです。
forEachは、設定されている配列から順に要素を取り出し、「each」という変数に設定してから<row>タグを実行する、という働きをします。<row>内では、${each[0]}というようにしてeachの配列から各要素をラベルとして出力しています。こうして、行のデータ表示を行っていたのです。
このforEachのように、制御を行うための属性というのがZKのコンポーネントにはいろいろと用意されています。「if ~ else ~」に相当する「if」「unless」属性、switch文に相当する「switch」「case」属性といったものです。これらを利用することで、コードを使わずに表示の制御を行うことができるのです。