CakePHP1.3.6:一覧表示にアンカーを張って、参照画面を実装する。
今回は、これまでに作った一覧表示画面を修正して、明細参照の画面を追加する。
方法としては、以下のように、一覧にあるIDにアンカーを張る。
ここで、アンカーをクリックすると、以下のようなデータを照会する画面に遷移するようにする。
ポイントは、アンカーを張る際に、普通はGETパラメータとして「id=xxx」のように記述する部分が、rewiteモジュールを使うことで、「/xxx」となる点。
customers_controller.phpにshowというアクション(メソッド)を作って、対応するので、「show/xxx」というアンカーを張ることになる。
コントローラーの修正
/app/controllers/customer_controller.phpを改修し、showメソッドを実装する。
<?php require_once '../vendors/MyConverter.class.php'; class CustomersController extends AppController{ public $name = 'Customers'; public $layout = 'myznala'; /** * * 初期画面(一覧表示) */ function index(){ $this->set('title_for_layout', "顧客の一覧"); $req=null; if(!empty($this->data)){ //サニタイズ $req = MyConverter::getRequestParams($this->data["Customer"]); $result = $this->Customer->find('all', array('conditions' => array('Customer.name like ?' => array("%{$req["name"]}%")), 'order' => array('Customer.timestamp DESC') ) ); }else{ $result = $this->Customer->find('all', array( 'order' => array('Customer.timestamp DESC') ) ); } $this->set('result',$result); } /** * * データの追加 */ function add(){ $this->set('title_for_layout', "顧客の登録"); if(!empty($this->data)){ // サニタイズ $this->data["Customer"] = MyConverter::getRequestParams($this->data["Customer"]); // 登録 $this->Customer->save($this->data); if($this->Customer->validates()){ $this->redirect('.'); } } } /** * * データの照会 * $paramsにIdが入ってくる。 */ function show($param){ $this->set('title_for_layout', "顧客の詳細"); $result=null; if(!empty($param)){ // Idフィールドによる検索 $result=$this->Customer->findById($param); } $this->set('result',$result); } } ?>
ここで、showアクションが引数をとることに注意。/show/xxxというアンカーから遷移した場合、この引数にxxxが入ってくる。
また、customersテーブルを検索する際に、findBy[フィールド名]というメソッドを使うようにした。
それと、addアクションでは登録後に一覧(indexページ)にリダイレクトする。新しく登録したデータは、メンテナンス頻度が高いので、一覧表をタイムスタンプフィールドの降順に並び変える。
ビューの作成
index.ctp
インデックス画面を、詳細画面へのアンカーを張るように修正する。
<h2>顧客の一覧</h2> <br> 名前で絞り込みをします。 <?php echo $form->create(null,array('type'=>'post','action'=>'.')); echo $form->text('Customer.name', array('size' => 10)); echo $form->end('送信'); ?> <table> <tr> <th>ID</th> <th>名前</th> <th>郵便番号</th> <th>住所</th> <th>電話</th> <th>携帯</th> <th>メール</th> <th>更新日</th> </tr> <?php foreach ($result as $arr){ echo '<tr>'; echo "<td><a href='./show/{$arr['Customer']['id']}'>{$arr['Customer']['id']}</a></td>"; echo "<td>{$arr['Customer']['name']}</td>"; echo "<td>{$arr['Customer']['zip']}</td>"; echo "<td>{$arr['Customer']['address']}</td>"; echo "<td>{$arr['Customer']['tel']}</td>"; echo "<td>{$arr['Customer']['mobile']}</td>"; echo "<td>{$arr['Customer']['mail']}</td>"; echo "<td>{$arr['Customer']['timestamp']}</td>"; echo '</tr>'; } ?> </table> <a href="add">登録</a>
show.ctp
showアクションに対応して、そのビューを作成する。コントローラー内で、ビューには、findByIdの内容をそのまま渡すが、Customerという添字の連想配列に格納されて、ビューに渡す。
<h2>顧客の詳細</h2> <br> <table> <?php echo "<tr><th>名前</th>"; echo "<td>{$result['Customer']['name']}</td>"; echo "</tr>"; echo "<tr><th>郵便番号</th>"; echo "<td>{$result['Customer']['zip']}</td>"; echo "</tr>"; echo "<tr><th>住所</th>"; echo "<td>{$result['Customer']['address']}</td>"; echo "</tr>"; echo "<tr><th>電話</th>"; echo "<td>{$result['Customer']['tel']}</td>"; echo "</tr>"; echo "<tr><th>携帯</th>"; echo "<td>{$result['Customer']['mobile']}</td>"; echo "</tr>"; echo "<tr><th>メール</th>"; echo "<td>{$result['Customer']['mail']}</td>"; echo "</tr>"; echo "<tr><th>メモ</th>"; echo "<td>{$result['Customer']['memo']}</td>"; echo "</tr>"; ?> </table> <a href="../">リストに戻る</a>
モデルの修正
モデルに変更はないが、先のログでバリデーションのテストを行ったので、テスト用のコード部分を削除する。
<?php require_once '../vendors/MyValidator.class.php'; class Customer extends AppModel { public $name = 'Customer'; public $validate = array( 'name'=>array( 'rule' => 'notEmpty', 'message' =>'入力してください' ), 'zip'=>array( array( 'rule' => array('checkZip','zip'), 'message' =>'形式がただしくありません'), array( 'rule' => 'notEmpty', 'message' =>'入力してください' ) ), 'address'=>array( 'rule' => 'notEmpty', 'message' =>'入力してください'), 'tel'=>array( 'rule' => 'notEmpty', 'message' =>'入力してください'), 'mail'=>array( 'rule' => 'notEmpty', 'message' =>'入力してください') ); public function checkZip($data,$name){ return MyValidator::validate('ja', 'isZip', $data[$name]); } } ?>