前提知識
INTER-Mediatorに関して、以下の内容をすでに知っている事を前提とします。
- data-im属性への記述によりフィールドの内容が表示されること
- TABLEタグを使った表の中で、複数のレコードが繰り返し表示されるようになっていること
- 一定数ごとのレコードを表示する仕組みと、表示範囲を切り替えるページネーションの仕組みがあること
- 定義ファイルのコンテキストには、検索条件が指定できること
作成例について
たくさんのレコード、そしてたくさんのフィールドがある場合、そのデータの一覧を表示して、ボタンをクリックするなどして移動したページで詳細を表示したり編集したりするような作りのユーザーインタフェースはよく利用されます。この種のユーザーインタフェースをマスター/ディテール、あるいは一覧と詳細といった呼び方をします。
サンプルデータベースには、商品マスターのテーブルがあります。その内容を一覧と詳細形式で表示したいとします。一般的なWebアプリケーションだと、それぞれ異なるページを用意して、ページ移動などの必要な機能を実装するということになります。一方、INTER-Mediatorでは、そうしたユーザーインタフェースを作りやすくした仕組みを組み込んでいます。一覧も詳細も、同一のページに表示して、必要に応じて表示と非表示を行うことで、一覧と詳細の動作を行っています。
サンプルの一覧のページからは「Practices」の「Master/Detail」にある「alternative navigation」をクリックすると、以下のようなページが表示されます。最初は、商品マスターの商品名と単価が見えている一覧が表示されています。ここで、「詳細」ボタンをクリックすると、クリックした商品に関する他のフィールドを、そのレコードだけ表示します。「一覧表示」ボタンをクリックすると、元の一覧のページが表示されます。
サンプルの一覧のページからは「Practices」の「Master/Detail」にある「split master/detail」をクリックすると、以下のようなページが表示されます。一覧と詳細が同時に表示されています。CSSの仕組みを利用して、それぞれのテーブルを左右に並ぶように配置しています。
左側の一覧で「詳細」ボタンをクリックすると、該当するレコードが右側に表示されます。つまり、右側は、左側のリストでクリックしたレコードの情報に逐次切り替わります。
ここで、右側の詳細表示の方が、テキストフィールドになっています。たとえば、単価を1200に修正したとします。修正をしてTabキーを押すなどすると、このレコードのunitpriceフィールドの値は1200に更新されます。
テキストフィールドからフォーカスが外れると同時に、左側の対応するフィールドも値が置き換わっています。このように、同一のフィールドがページ内の複数の箇所に見えている場合には、1つの修正が他の要素へ自動的に反映されるようになっています。(書式の反映に関しては、Ver.5.0より後に修正をおこなう予定です。)
定義ファイル
定義ファイルのSamples/Practices/nav1.phpの内容は以下の通りです。一覧と詳細が切り替わるnavi1.phpと、左右に表示されるnavi2.phpの2つの定義ファイルがありますが、1箇所の設定を除いて同一のものです。
まず、一覧と詳細は、基本的には同一のテーブルがデータソースになるはずです。しかしながら、INTER-Mediatorでは、それぞれ、異なるコンテキストして定義します。productテーブルをもとに、一覧用のproductlistコンテキストと、詳細用のproductdetailコンテキストを用意します。いずれも、viewキーの値がproductとなっており、同じproductテーブルから得られるコンテキストであることがわかります。一覧と詳細を構成するには、それぞれのコンテキストにnavi-controlキーに値を指定します。一覧側は「master」、詳細側は「detail」と指定するのが基本です。masterだけだと、一覧と詳細は同時に表示され、詳細側にはマスターに切り替わるボタンは表示されません。master-hideだと、一覧と詳細が切り替わり、詳細側に一覧を表示するボタンが追加されます。detail、あるいはdetail-downなら詳細の末尾に、detail-topなら詳細の冒頭に、一覧に移動するボタンを表示します。なお、master側のコンテキストでは、必ず「詳細」ボタンが追加されます。
データベースはMySQLを使うのでdb-classは「PDO」を指定します。それ以外の接続情報、アカウント、パスワードは、INTER-Mediator/params.phpファイルにあるものをそのまま使います。INTER-Mediatorのサンプルファイルをそのまま参照できる状態であれば、特に変更する必要はありません。
require_once(dirname(__FILE__) . '/../../INTER-Mediator.php');
IM_Entry(
array(
array(
'records' => 10,
'name' => 'productlist',
'view' => 'product',
'key' => 'id',
'sort' => array(array('field' => 'name', 'direction' => 'ASC'),),
'navi-control' => 'master-hide',
),
array(
'records' => 1,
'name' => 'productdetail',
'view' => 'product',
'table' => 'product',
'key' => 'id',
'navi-control' => 'detail-top',
),
),
array(
'formatter' => array(
array('field' => 'product@unitprice', 'converter-class' => 'Number', 'parameter' => '0'),
),
),
array('db-class' => 'PDO'),
false
);
ページファイル
ページファイルについては、ボディ部のみを示します。もちろん、ヘッダ部で、前述の定義ファイルSCRIPTタグで読み込んだ状態になっています。一覧を表示するTABLEと詳細を表示するTABLEが定義されているだけです。左右のレイアウトをしやすいように、それぞれDIVタグ要素に含めてあります。それぞれのTABLEタグ要素内では、productlistコンテキストと、productdetailコンテキストを利用したターゲット指定があるだけで、特に何も特別な記述はありません。
<body onload="INTERMediator.construct(true);">
<!-- Table for the list view -->
<div id="listarea" style="float:left; margin-right: 24px;">
<table border="1">
<thead>
<tr>
<th></th><th>name</th><th>unitprice</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td data-im="productlist@name"></td>
<td class="price" data-im="productlist@unitprice"></td>
</tr>
</tbody>
</table>
</div>
<!-- Table for the detail view -->
<div id="detailarea">
<table border="1">
<tbody>
<tr>
<th>id</th>
<td data-im="productdetail@id"></td>
</tr>
<tr>
<th>name</th>
<td><input type="text" size="60" data-im="productdetail@name"></td>
</tr>
<tr>
<th>unitprice</th>
<td><input type="text" size="60" data-im="productdetail@unitprice"></td>
</tr>
<tr>
<th>photofile</th>
<td><input type="text" size="60" data-im="productdetail@photofile"></td>
</tr>
<tr>
<th>acknowledgement</th>
<td><input type="text" size="60" data-im="productdetail@acknowledgement"></td>
</tr>
<tr>
<th>ack_link</th>
<td><input type="text" size="60" data-im="productdetail@ack_link"></td>
</tr>
<tr>
<th>photofile</th>
<td><img src="../Sample_products/images/" data-im="productdetail@photofile@#src"></td>
</tr>
</tbody>
</table>
</div>
<div style="clear: both"/>
</body>
まとめ
一覧と詳細を実装するときには、それぞれを異なるコンテキストで1ページ内に配置します。そして、コンテキストにnavi-controlキーの値を指定することで、それぞれが連携して、一覧と詳細の動作を行うようになります。そのように動作させるためにプログラムを記述する必要はまったくありません。