INTER-Mediator Ver.5.4-devでは、クロステーブルの作成ができるようになっています。ここでのクロステーブルは、表があって、いちばん上の列と、いちばん左の列がラベルとなっており、そのラベルの交差するセルには、ラベルに関連するデータが表示されるというものです。例えば、いちばん上の列には自社の「支店」が並び、いちばん左の列には年月が並ぶとすると、その交差するセルには、特定の支店の特定の年月の売り上げが見えるというものです。サンプルファイルはSamples/Practice/crosstable.htmlおよびcrosstable.phpにあります。
まず、クロステーブルを作るには、3つの異なるコンテキストを定義します。1つは列見出し(以下のコードではitem)、1つは行見出し(以下のコードではcustomer)、そして交差するセルに設定されるデータのコンテキスト(同じくsalessummary)です。列見出し、行見出しのコンテキストについては通常と変わりありません。また、列か行かの区別も、定義ファイル内では設定しなくても構いません。行列の見出しのコンテキストでは、検索条件や並べ替えフィールドの指定などももちろん可能です。以下の例では、元のデータが多いこともあるので、意図的に絞り込んでいます。交差するセルのコンテキスト「salessummary」では、relationキーの指定を必ず2項目行います。1項目は列見出し、2項目目は行見出しとの関連付けになります。item、customerともに、主キーはidフィールドです。これに対応するsalessumarryコンテキストのフィールドはitem_idとcustomer_idです。すなわち、列見出し、行見出しの対応するレコードとのリレーションシップを利用して、交差するデータの配置を決めています。
array( 'name' => 'item', 'table' => 'dummy', 'view' => 'item_master', 'records' => 100000, 'maxrecords' => 100000, 'key' => 'id', 'query' => array( array('field' => 'id', 'value' => 25, 'operator' => '>='), array('field' => 'id', 'value' => 35, 'operator' => '<='), ), 'sort' => array(array('field' => 'id', 'direction' => 'asc')), ), array( 'name' => 'customer', 'table' => 'dummy', 'view' => 'customer', 'records' => 100000, 'maxrecords' => 100000, 'key' => 'id', 'query' => array( array('field' => 'id', 'value' => 250, 'operator' => '>='), array('field' => 'id', 'value' => 259, 'operator' => '<='), ), 'sort' => array(array('field' => 'id', 'direction' => 'asc')), ), array( 'name' => 'salessummary', 'table' => 'dummy', 'view' => 'saleslog', 'records' => 100000, 'key' => 'id', 'relation' => array( array('foreign-key' => 'item_id', 'join-field' => 'id', 'operator' => '=',), array('foreign-key' => 'customer_id', 'join-field' => 'id', 'operator' => '=',), ), ),
ページファイルのクロステーブルの部分は、2セルずつの2行の表として作ります。それよりも多い場合や少ない場合はダメで、要するに2行2列のテーブルを必ず用意します。そして、エンクロージャーになるtbodyタグのdata-im-control属性を「cross-table」とします。これら4つのセルと2つの行は取り除かれ、初期状態として、TRタグに左上のセルを入れた状態にします。この左上のセル内部は、ページファイル側での定義通りにレイアウトされます。
<table> <tbody data-im-control="cross-table"> <tr> <th></th> <th> <div data-im="item@id"></div> <div data-im="item@name"></div> </th> </tr> <tr> <th> <div data-im="customer@id"></div> <div data-im="customer@name"></div> </th> <td> <div data-im="salessummary@qty"></div> <div data-im="salessummary@total"></div> </td> </tr> </tbody> </table>
続いて、1行目のTRタグをエンクロージャーに、そしてページファイルにあった右上のセルをリピーターとして、ページ合成を行います。つまり、このBのセルには、列見出しになるコンテキストの名前と、データベースから得られるフィールド名をdata-im属性として持つターゲットノードを記述しておきます。その結果、データベースアクセスが発生し、この場合はitemテーブルから一部のレコードを取り出して、それらを列見出しとして並べます。
さらに行見出しの処理になります。今度は、TBODYタグをエンクロージャー、そしてTRタグにページファイルの左下のセルを入れたものをリピーターとして、ページ合成を行います。つまり、行見出しだけをまずは作成します。
ここまでは、エンクロージャーとリピーターの違いはありますが、通常のページ合成と同じです。クロステーブルでは、ここで、次の図のように、交差する部分のセルに、一旦、ページファイルのテーブルの右下のセルを全て並べます。そして、コンテキストに応じたデータベースアクセスを行い、交差する部分に入るデータがあれば、対応するセルに値を設定します。列見出しあるいは行見出しに登場しないレコードと対応するものは無視されます。
サンプルの出力結果は以下のようなものです。2つのセルにしかデータは入っていません。なお、ここでの交差するセルに対応したコンテキスト内に、同一のセルに対応するものが複数ある場合には、中途半端にマージされます。コンテキスト内は、例えばSQLのビュー等を使うなどして、1つのセルに対応するレコードは0ないしは1個になるようにしてください。