sample1

The following example shows how to use TRepeater to display tabular data.
以下の例は、表データを表示するためにどのようにTRepeaterを使うかを示します。

TRY & ERROR

いくつか、サンプルがあって、一気に翻訳すると新しいことで”いっぱいいっぱいになりそうなので、いったんここで、サンプルを作ってみます。まずは、単純に
<h1>TRepeater</h1>
<table cellpadding='2'>
<com:TRepeater ID="Repeater" EnableViewState="false">
 <prop:ItemTemplate>
  <tr style="background-color:#BFCFFF">
   <td><%#$this->Data['id']%></td>
   <td><%#$this->Data['name']%></td>
   <td><%#$this->Data['quantity']%></td>
   <td><%#$this->Data['price']%></td>
   <td><%#$this->Data['imported']?'Yes':'No'%></td>
  </tr>
 </prop:ItemTemplate>
</com:TRepeater>
</table>
と記載します。ItemTemplate タグは、通常の繰り返し用のタグと書いてありましたね。クラスファイルのほうには、サンプルのコードそのまま、
class TRepeaterSample extends TPage
{
 protected function getData()
 {
  return array(
  array 'id'=>'ITN001','name'=>'Motherboard','quantity'=>1,'price'=>100.00,
   'imported'=>true),
  array('id'=>'ITN002','name'=>'CPU','quantity'=>1,'price'=>150.00,
   'imported'=>true),
  array('id'=>'ITN003','name'=>'Harddrive','quantity'=>2,'price'=>80.00,
   'imported'=>true),
  array('id'=>'ITN004','name'=>'Sound card','quantity'=>1,'price'=>40.00,
   'imported'=>false),
  array('id'=>'ITN005','name'=>'Video card','quantity'=>1,'price'=>150.00,
   'imported'=>true),
  array('id'=>'ITN006','name'=>'Keyboard','quantity'=>1,'price'=>20.00,
   'imported'=>false),
  array('id'=>'ITN007','name'=>'Monitor','quantity'=>2,'price'=>300.00,
   'imported'=>true),
  array('id'=>'ITN008','name'=>'CDRW drive','quantity'=>1,'price'=>40.00,
   'imported'=>true),
  array('id'=>'ITN009','name'=>'Cooling fan','quantity'=>2,'price'=>10.00,
   'imported'=>false),
  array('id'=>'ITN010','name'=>'Video camera','quantity'=>20,'price'=>30.00,
   'imported'=>true),
  array('id'=>'ITN011','name'=>'Card reader','quantity'=>10,'price'=>24.00,
   'imported'=>true),
  array('id'=>'ITN012','name'=>'Floppy drive','quantity'=>50,'price'=>12.00,
   'imported'=>false),
  array('id'=>'ITN013','name'=>'CD drive','quantity'=>25,'price'=>20.00,
   'imported'=>true),
  array('id'=>'ITN014','name'=>'DVD drive','quantity'=>15,'price'=>80.00,
   'imported'=>true),
  array('id'=>'ITN015','name'=>'Mouse pad','quantity'=>50,'price'=>5.00,
   'imported'=>false),
  array('id'=>'ITN016','name'=>'Network cable','quantity'=>40,'price'=>8.00,
   'imported'=>true),
  array('id'=>'ITN017','name'=>'Case','quantity'=>8,'price'=>65.00,
   'imported'=>false),
  array('id'=>'ITN018','name'=>'Surge protector','quantity'=>45,
   'price'=>15.00,'imported'=>false),
  array('id'=>'ITN019','name'=>'Speaker','quantity'=>35,'price'=>65.00,
  'imported'=>false),
 );
}
 public function onLoad($param)
 {
  parent::onLoad($param);
  if(!$this->IsPostBack)
  {
   $this->Repeater->DataSource=$this->getData();
   $this->Repeater->dataBind();
  }
 }
}
を記載します。一応、これで、5列のテーブルが表示されます。私は、新発見だったのですが、getData メソッドの構文は、array の中に、array が組み込まれていて、内側の配列が、テーブルのデータに対応しています。それがさらに配列になっていて、この一行が、テーブルの列に対応しているという構造です。Data['アイテム名'] という指定で、ページには記載されていますね。 これを見ると、やっぱりデータベースからのデータリンクだな・・・。と思わされます。(到底こんなクラスは書かないだろうと思ってしまいます。) ここでは、とりあえず、ということで、やってみました。まずは、データベースのほうですが、私はMysqlで、対応しているテーブルを作りました。
create table sample1(
 id int not null primary key auto_increment,
 name varchar(20),
 quantity int,
 price int,
 imported boolean);
)
という感じですね。サンプルデータもいくつか追加しておいてください。次に、必要クラス System.Data. * をコンフィグファイル、application.xml の<paths>タグ内に追加します。
いよいよ getData メソッドをDB対応に書き換えます。
$dsn='mysql:host=localhost;dbname=test';
$username='root';
$password='';

$connection=new TDbConnection($dsn,$username,$password);
$connection->Active=true;

$sql='select * from sample1';
$command=$connection->createCommand($sql);
 $dataReader=$command->query();
 $dataReader->bindColumn(1,$id);
 $dataReader->bindColumn(2,$name);
 $dataReader->bindColumn(3,$quantity);
 $dataReader->bindColumn(4,$price);
 $dataReader->bindColumn(5,$imported);

 $rArray=array();
 while($dataReader->read()!==false){
  array_push($rArray,array(
   'id'=>$id,
   'name'=>$name,
   'quantity'=>$quantity,
   'price'=>$price,
   'imported'=>$imported));
 }

 $connection->Active=false;
 return $rArray;
DBとのデータのやり取り方法は、いろいろあるようですし、TRepeater へのデータバインドも、いくつか方法があると書いてありますが、直感的に分かりやすいこの方法をやってみました。まず、DB名、ユーザー名、パスワードを設定し、コネクションを構築します。「えっ ここにユーザー名、パスワード書いて大丈夫なの?」 と思うかも知れませんが、このクラスファイルのある、ところは、 protected ディレクトリ内にあり、このディレクトリは、ユーザーからのすべての権限をとっておく場所です。(700の設定ですね) なので、何を書いてもここに直接アクセスされる心配はありません。その以下は、ごらんの通りで、最後は、Arrayへ値を設定し、返しています。
次に、sample1にあるものをひとつひとつ試していきますが、まずは、行を交互にスタイル変更させるAlternatingItemTemplate です。次のタグをTRepeaterコントロール内に追加します。
<prop:AlternatingItemTemplate>
<tr style="background-color:#0080ff">
 <td>
 <td>
 <td>
 <td>
 <td>
</tr>
</prop:AlternatingItemTemplate>
これを追加することで、偶数行のスタイルが変更になります。通常のItemTemplatの前に追加しても、後に追加してもやはり偶数行の設定が変更になります。偶数行のスタイル用ということを覚えておくべきだと思います。
次に、ヘッダーです。以下のプロパティを追加します。場所は、コントロール内であれば、前後は問わないようです。
<prop:HeaderTemplate>
 <tr style="color:white;background-color:black">
  <th>ID
  <th>Name
  <th>Quantity
  <th>Price
  <th>Imported
 </tr>
</prop:HeaderTemplate>
これで、問題なく標題が付きますが、sample1では、<table>タグを内包して書いていますが、何の意味があるのか不明です。最後にフッターです。
<prop:FooterTemplate>
<tr style="color:white;background-color:black;text-align:center;">
 <td colspan="5">Computer Parts Inventory
しかし、このヘッダーフッターはTRepeaterにおいて、何の意味があるのかいまいち不明です。繰り返しはないわけなので、
<table>
 <tr>ヘッダーの内容
  <TRepeater>のコントロール
 </tr>
 <tr>フッターの内容</tr>
</table>

と書いてしまえば良いような・・・・?ちなみに、フッターとしては、トータルがほしいと思うのが、人情(?)だと思うので、との間に

<tr style="color:white;background-color:black;text-align:center;">
 <td colspan="2">Total
 <td>
 <td>
 <td></td>
</tr>
と追加し、クラスファイルのgetDataメソッドの後半を以下の様に書き換えます。
$rArray=array();
$quantity_total=0;
$price_total=0;
 while($dataReader->read()!==false)
 {
  array_push($rArray,array
   ('id'=>$id,
    'name'=>$name,
    'quantity'=>$quantity,
    'price'=>$price,
    'imported'=>$imported
   )
  );
 $quantity_total=$quantity_total+$quantity;
 $price_total=$price_total+$price;
 }

 $this->quantity_total->Text=$quantity_total;
 $this->price_total->Text=$price_total;
 $connection->Active=false;
 return $rArray;

下線部分を追加しました。この部分が、ページファイルの数量と金額の合計のコントロールに値を追加しています。このサンプルの結果は、

http://felix-labo.org/myprado/?page=TRepeaterSample

でごらんになれます。