フォーム入力画面と確認画面で共通で使えるXformHelper
Cakephp1.2.6
追記(2010/12/16):
コメントでPHP5.3の動作不具合報告を頂いたので対応しました。報告ありがとうございました。現状、PHP5.2.15, PHP5.3.4で確認し、CakePHPは1.3.6, 1.2.9で確認しました。gitの最新版か、githubにあるダウンロードボタンから0.02というバージョンのコードをダウンロードしてご利用ください。
入力項目が多くなると、確認画面を作るのも時間がかかりますよね、面倒ですし。今までは、確認画面で別途 $form->value使うとか、Postの値をそのまま表示するようにしてたのですが、デザインが入力画面とほぼ同じなのに別に実装するのがなんだかなと思ってました。それに嫌気がさして、フォーム入力画面でも確認画面でも同じメソッドで、フォームタグと値の表示を切り替えるXformHelperを開発しました。
機能は色々つけてあります。大体のメソッドはカバーできてるんじゃないかと思いますが、不具合があれば教えてください。
機能一覧
- 入力画面にて、formヘルパーと同じメソッドで同じ結果を出力
- 確認画面にて、formヘルパーと同じメソッドでPostされた値を出力
- その他の入力画面機能
- passwordフィールドの値は常に空にする(プロパティの変更で回避可能)
- 日付関係のセパレータを拡張(プロパティにて、日本語の年月日、時分をセパレータに指定可能)
- その他の確認画面機能
- 出力はエスケープ、nl2brを自動でかける(プロパティの変更で回避可能)
- passwordフィールドは、*****の固定文字列を表示(ただしinput()ではなくpassword()メソッドの利用に限り)
- checkboxなどの複数選択時は、カンマ区切りで表示(プロパティの変更でカンマ以外も指定可能)
- 日付関係のセパレータを指定可能(2010年2月24日という表示が可能)
前提
入力画面と確認画面の制御方法は、下記の2パターンあり、どちらかを実行ください。
1. コントローラの確認画面のアクションで、$this->params['xformHelperConfirmFlag'] = true;をセット(バリデーション成功後が望ましい)
2. 確認画面のviewファイルの最初に、$xformjp->confirmScreenFlag = true; とする
使い方
http://github.com/ichikaway/xformHelper/downloads
ここからダウンロード、もしくはgit cloneして設置下さい。
views/helpers/xform.php
views/helpers/xformjp.php
xform.phpが基本的な実装で、xformjpはxformを継承して、プロパティのみ日本語仕様(自分仕様で不要なものは極力false)に変更してます。お好きなほうをご利用下さい。xformjpを自分用に変更しても良いですし、myxform.phpみたいな別のクラスを作るのも良いかと思います。
xformを使ってプロパティのみ変更したい場合は、コントローラからhelpersプロパティで宣言する際に、下記の様に配列の引数で指定すれば変更できます。
<?php var $helpers = array('Html', 'Form', 'xform' => array('changeDatetimeSeparator' => array( 'datefmt' => array( 'year' => '年', 'month' => '月', 'day' => '日', 'afterDateTag' => ' ', //dateとtimeの表示の間に入れる文字列 ), 'timefmt' => array( 'hour' => '時', 'min' => '分', 'meridian' => '', ) ) ) );
上記のように、引数が多くなると面倒なので、自分はxformjpヘルパーを作りました。
これ以降は、xformjpヘルパーを前提に書きますが、xformヘルパーを利用する場合は全てxformjpをxformに置き換えて頂ければ大丈夫です。
コントローラ設定
<?php var $helpers = array('Html', 'Form', 'xformjp'); //入力画面アクション function add(){ } //確認画面アクション function add_confirm(){ //確認画面の表示に切り替える(バリデーション成功後が望ましい) $this->params['xformHelperConfirmFlag'] = true; }
Viewの設定
基本的には、使っているViewの$formを$xformjpに置換するだけで動きます(上記のようにコントローラ側で表示切替をする場合)
自分の場合は、$xformjp::input()関係を切り出してエレメント化して、入力画面用add.ctpと確認画面用add_confonfirm.ctpから同じエレメントを呼んでます。
まずは入力画面用add.ctp
<?php echo $xformjp->create('Modelname', array('action' => 'add_confirm'));?> <?php //外部ファイル読み込み //views/elements/base_input.ctp echo $this->element("base_input"); ?> <?php echo $xformjp->submit('確認', array('name' => 'confirm_action')); ?> <?php echo $xformjp->end();?>
次に確認画面用add_confirm.ctp
<?php //外部ファイル読み込み //views/elements/base_input.ctp echo $this->element("base_input"); ?> <?php echo $xformjp->create('Modelname', array('action' => 'add_finish'));?> ここにHiddenでPostデータを出力 or セッションでPostデータを管理 <?php echo $xformjp->submit('送信', array('name' => 'finish')); ?> <?php echo $xformjp->submit('戻る', array('name' => 'back')); ?> <?php echo $xformjp->end();?>
hiddenでデータを一括で書き出す場合は、「よくある確認画面でのhiddenデータの持ち回り ver2」を使うと便利です! その更に改良版のformhiddenヘルパーをgithubにあげてあります。
最後に、共通で呼んでるエレメント base_input.ctp
今回は、text, password, select, checkboxを利用。
名前 <?php echo $xformjp->input('name'); ?> パスワード <?php echo $xformjp->password('password'); ?> メール <?php echo $xformjp->input('email'); ?> <?php if($xformjp->checkConfirmScreen() === false) : // 確認画面では非表示 ?> <?php echo $xformjp->input('email_conf'); ?>(確認) <?php endif; ?> チェックボックス <?php echo $xformjp->input('checkbox1', array( 'type' => 'select', 'multiple' => 'checkbox', 'options' => array('key1' => 'checkテスト', 'key2' => 'checkテスト2'), ) ); ?> セレクト <?php echo $xformjp->input( 'select1' , array( 'type' => 'select', 'options'=> array('key1' => 'selectテスト', 'key2' => 'selectテスト2'), 'label' => false, 'empty' => '', ) ); ?>
メールの入力確認などは、確認画面で出力したくないので、$xformjp->checkConfirmScreen()を使って判定しています。falseが返ってきたら入力画面、trueが返ってきたら確認画面なので、これを使えば細かく制御できます。
既存のシステムで利用する場合は、views以下のフォルダのctpファイルで、$formを$xformjpに一括置換すればOK。あとはコントローラにちょっと追記するだけ。viewファイルの文字列一括置換は、例えばLinuxなどの場合であれば、下記のようにするだけです。
cd app/views find . -type f -name "*.ctp" -exec perl -p -i -e 's/\$xform/\$xformjp/g' {} \;
これで面倒な確認画面がちょっと楽に実装できるようになった! 改良や不具合修正があれば連絡してもらえるとうれしいです。Twitterとかgithubのpullリクエストなどで。
Enjoy!