第3回 HTML_QuickFormを使ってみよう(パート2) ご意見・ご感想
たぬき 今日の先生の機嫌はどうかなあ?
先生 さあ今日は前回のHTML_QuickFormの続きをやりますね。
前回のサンプルはテキストだけだったので、今回はselect、text、radio、checkbox、
textareaを使ってみましょう。
今日作るのは、「奥進システムとあなたの相性チェック」プログラムです。
たぬき 夏休みが終わったから、先生普通にもどったやん。
先生 画面イメージはこんな感じ。
たぬき なんでこうもりやねん。趣味悪いなあ。
先生 前回作った画面定義クラスのsetItemメソッドにいろいろな要素を追加して、今回はこんな感じになります。
001:  <?php
002:      // フォームの項目を定義
003:      function setItem() {
004:          // ヘッダー
005:          $this->_form->addElement('header', 'hdrFavorite',
006:                           'あなたの好みを教えてください。');
007:  
008:          // 「好きな色」の選択セレクト
009:          $colorArr = array("0"=>"赤",
010:                            "1"=>"オレンジ",
011:                            "2"=>"黄",
012:                            "3"=>"緑",
013:                            "4"=>"青",
014:                            "5"=>"紫",
015:                            "6"=>"水色",
016:                            "7"=>"白");
017:          $this->_form->addElement('select', 'selColor', '好きな色:', $colorArr);
018:  
019:          // 「好きな色」のテキスト
020:          $this->_form->addElement('text', 'txtColor',
021:                               '好きな色      :<BR>(その他の場合)');
022:  
023:          // 「好きな動物」ラジオボタンのグループ 
024:          //  第二引数の「名称」が同じボタンの中から一つだけが選択できる。
025:          $animalRdoArr[] = 
026:              &HTML_QuickForm::createElement('radio', 'rdoAnimal', null, '犬', 0);
027:          $animalRdoArr[] = 
028:              &HTML_QuickForm::createElement('radio', 'rdoAnimal', null, '猫', 1);
029:          $animalRdoArr[] = 
030:              &HTML_QuickForm::createElement(
031:                  'radio','rdoAnimal', null, 'こうもり', 2
032:                  );
033:          $this->_form->addGroup($animalRdoArr, null, '好きな動物:', '&nbsp;');
034:  
035:          // 「好きな言語」チェックボタンのグループ
036:          $lngChkArr[] =
037:            &HTML_QuickForm::createElement('checkbox', 'chkC', null, 'C言語');
038:          $lngChkArr[] = 
039:            &HTML_QuickForm::createElement('checkbox', 'chkCpp', null, 'C++');
040:          $lngChkArr[] =
041:            &HTML_QuickForm::createElement('checkbox', 'chkCobol', null, 'COBOL');
042:          $lngChkArr[] =
043:            &HTML_QuickForm::createElement('checkbox', 'chkPhp', null, 'PHP');
044:          $lngChkArr[] =
045:            &HTML_QuickForm::createElement('checkbox', 'chkRpg', null, 'RPG');
046:          $lngChkArr[] =
047:            &HTML_QuickForm::createElement('checkbox', 'chkVb', null, 'VB');
048:          $lngChkArr[] =
049:            &HTML_QuickForm::createElement('checkbox', 'chkVc', null, 'VC');
050:          $lngChkArr[] =
051:            &HTML_QuickForm::createElement('checkbox', 'chkJava', null, 'java');
052:          $lngChkArr[] =
053:            &HTML_QuickForm::createElement('checkbox', 'chkAsp', null, 'ASP');
054:          $lngChkArr[] =
055:            &HTML_QuickForm::createElement('checkbox', 'chkJsp', null, 'JSP');
056:          $lngChkArr[] =
057:            &HTML_QuickForm::createElement('checkbox', 'chkPerl', null, 'Perl');
058:          $this->_form->addGroup($lngChkArr, null, '好きな言語:', '&nbsp;');
059:  
060:          // ヘッダー
061:          $this->_form->addElement('header', 'hdrText',
062:                                       'ハンドルネームと感想をお願いします。');
063:          // 「ハンドルネーム」のテキスト
064:          $this->_form->addElement('text', 'txtName', 'ハンドルネーム:');
065:          $this->_form->setRequiredNote (
066:                      '<font color="#e66666">*</font>必須項目です');
067:          // 「感想」のテキストエリア
068:          $this->_form->addElement('textarea', 'txaImp', '感想:');
069:      }
070:  ?>
図1.setItem
たぬき 今日は、ぼく、夏休み疲れ・・・
先生 難しい? 簡単に説明すると、まず addElementの引数は要素によってまちまちです。setItemでしてることはこっちも読むと分かると思うよ。
たぬき 先生それって説明になってへんって…
先生 じゃあ、次は入力チェックを追加してみましょう。
001:  <?php
002:      // サーバ側でチェックするルール
003:      function setServerRule() {
004:          // 必須入力項目を設定
005:          $this->_form->addRule('txtName', '入力してください', 'required');
006:      }
007:  
008:      // クライアント側でチェックするルール
009:      function setClientRule() {
010:          // 必須入力項目が入力されていない時のエラーメッセージ表示
011:          $this->_form->setJsWarnings('必須項目を入力してください。','');
012:          $this->_form->addRule(
013:              'txtName', 'ハンドルネーム', 'required', '', 'client'
014:              );
015:      }
016:  
017:      // 正しく入力されているかチェックする。
018:      function chkValidate() {
019:          return $this->_form->validate();
020:      }
021:  
022:      // 入力された値を取得する。
023:      //      戻り値:要素名と入力された値の連想配列
024:      function getVals() {
025:          return $this->_form->exportValues();
026:      }
027:  }
028:  ?>
図2.入力チェック
先生 addRuleではどの項目でどんなチェックをするかを定義します。
setServerRuleメソッドではサーバ側でのチェックを定義してます。これを定義してchkValidateメソッドを呼ぶと、ユーザの入力が適正かどうかチェックします。
setClientRuleメソッドではクライアント側でのチェックを定義してるんだけど、javascriptを生成してくれるのよ。
たぬき へえ〜、便利やん。すごいっ!!!
でも先生、何でサーバ側とクライアント側の両方のチェックが入ってんの?
先生 javascriptが動かせないブラウザの場合もあるから、サーバー側のチェックを入れておかないといけないのよ。 chkValidate()でサーバ側でのチェックを実行し入力が正しいかどうか確認します。
getVals()ではchkValidateでチェックした正しい値の連想配列を取得できます。
これで画面定義クラスの変更は完了。
でも、前回の画面定義クラスと今回の画面定義クラスは全く同じメソッドもあるでしょ?
ってことはいろんなフォームで共通している部分をまとめた基底クラスを作って、フォームを作る時はそれを継承するようにしたらええやん!
共通して使うであろうメソッドをまとめたクラスは以下の通り。
001:  <?php
002:  // QuickFormとSmartyを使用したフォームの基底クラス
003:  require_once "Smarty.class.php";
004:  require_once "HTML/QuickForm.php";
005:  require_once "HTML/QuickForm/Renderer/ArraySmarty.php";
006:  
007:  // 相性判定フォームクラス
008:  class Okushin_QF_Form {
009:      var $_form;
010:  
011:      // コンストラクタ
012:      //      $argAction : 「送信」ボタンのリンク先
013:      function Okushin_QF_Form($frmName, $argAction) {
014:          $this->_form = new HTML_QuickForm($frmName, 'post', $argAction);
015:      }
016:  
017:      // 「送信」ボタンを作る
018:      //      $argBtnName : ボタンの名前
019:      function setSubmit($argSubmitName) {
020:          $buttons[] = &HTML_QuickForm::createElement(
021:              'submit', $argSubmitName, '送信'
022:              );
023:          $this->_form->addGroup($buttons, "BTNG", null, '&nbsp;');
024:      }
025:  
026:      // 「戻る」ボタンと「送信」ボタンを作る
027:      //      $argRtnName    : 「戻る」ボタンの名前
028:      //      $argSubmitName : 「送信」ボタンの名前
029:      function setReturnSubmit($argRtnName, $argSubmitName) {
030:          $buttons[] = &HTML_QuickForm::createElement(
031:              'submit', $argRtnName, '戻る'
032:              );
033:          $buttons[] = &HTML_QuickForm::createElement(
034:              'submit', $argSubmitName, '送信'
035:              );
036:          $this->_form->addGroup($buttons, "BTNG", null, '&nbsp;');
037:      }
038:  
039:      // 「戻る」ボタンを作る
040:      //      $argBtnName : ボタンの名前
041:      function setReturn($argRtnName) {
042:          $buttons[] = &HTML_QuickForm::createElement(
043:              'submit', $argRtnName, '戻る'
044:              );
045:          $this->_form->addGroup($buttons, "BTNG", null, '&nbsp;');
046:      }
047:  
048:      // 正しく入力されているかチェックする。
049:      function chkValidate() {
050:          return $this->_form->validate();
051:      }
052:  
053:      // 入力された値を取得する。
054:      //      戻り値:要素名と入力された値の連想配列
055:      function getVals() {
056:          return $this->_form->exportValues();
057:      }
058:  
059:      // 要素へ値を設定する(今は使ってない)
060:      //      $vals:要素名と設定する値の連想配列
061:      function setVals($vals) {
062:          $this->_form->setDefaults($vals);
063:      }
064:  
065:      // 画面を表示する
066:      function dispForm() {
067:          $this->_form->display();
068:      }
069:  
070:      // 画面をフリーズする
071:      function freezeForm() {
072:          $this->_form->freeze();
073:      }
074:  }
075:  ?>
図2.OkushinQFFrm.php(基底クラス)
先生 次に前回のindex.phpを変更します。
001:  <html>
002:  <head>
003:  <title>「奥進システムとあなたの相性チェック!」</title>
004:  <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
005:  </head>
006:  <body>
007:  <?php
008:  require_once "./CFrmTanuki.php";
009:  $frmIndex = new CFrmTanuki('index.php');
010:  $frmIndex->setItem();
011:  
012:  if (isset($_POST["SUBMIT_INDEX"])) {
013:  // 確認画面 (入力画面で「送信」クリック時)
014:      $frmIndex->setServerRule();    // 入力チェックルール設定
015:      // 入力チェック実行
016:      if ($frmIndex->chkValidate()) {
017:          // 入力が正しい時は「戻る」ボタンと「送信」ボタンを表示
018:          $frmIndex->setReturnSubmit('RETURN_CONF', 'SUBMIT_CONF');
019:      } else {
020:          // 入力が不正な時は「戻る」ボタンのみを表示
021:          $frmIndex->setReturn('RETURN_CONF');
022:      }
023:      // 画面表示
024:      $frmIndex->freezeForm();    // 要素を凍結
025:      $frmIndex->dispForm();      // 表示
026:  } elseif (isset($_POST["SUBMIT_CONF"])) {
027:  // 採点画面 (確認画面で「送信」クリック時)
028:      // 入力値を受け取るためにsetItemを実行。
029:      // 表示はしない。
030:      $frmIndex->setServerRule();
031:      if ($frmIndex->chkValidate()) {
032:          // 入力結果を$valsに格納
033:          $vals = $frmIndex->getVals();
034:          // 採点処理を実行
035:          require_once "./ok.php";
036:      }
037:  } else {
038:  // 入力画面表示 (最初と確認画面で「戻る」クリック時)
039:      $frmIndex->setClientRule();    // 入力チェックルール設定
040:      $frmIndex->setSubmit("SUBMIT_INDEX");
041:      $frmIndex->dispForm();
042:  }
043:  ?>
044:  </body>
045:  </html>
図2.index.php
先生 入力画面は前回と違うのは40行目でクライアント側の入力チェックを呼んでることだけ。
次に確認画面は、13行目でサーバ側の入力チェックの処理を加えてます。
最後に結果画面、これも30行目でサーバ側チェックを追加して、31行目でchkValidateを実行した後、33行目でgetValsを実行し、入力された値を取得します。
そして今回は「相性チェックプログラム」なので、診断結果のみを表示するようにします。(ok.phpで採点処理を実行)
これで 「奥進システムとあなたの相性チェックプログラム」作成完了! たぬき君やってみて。
たぬき えーっと、好きな色は「緑」で、好きな動物は「こうもり」で……、「送信」…「送信」…っと。
「すごく良い」やって!
先生 へぇ…。(この子大丈夫か!?)
じゃあこれでHTML_QuickFormはおしまい。次回はいよいよSmartyへ!

インフォメーションへ戻る 第1回 PHPのコードとHTMLタグ コラム
  第2回 HTML_QuickFormを使ってみよう
  第3回 HTML_QuickFormを使ってみよう(パート2) HTML_QuickForm Memo
  第4回 Smartyを使ってみよう HTML_QuickForm Menu
  第5回 HTML_QuickFormとSmartyを使ってみよう HTML_QuickForm Smarty Tips
  第6回 HTML_QuickFormとSmartyを使ってみよう(パート2) Mojavi Memo
  第7回 実践編 HTML_QuickFormとSmartyを使ってみてどうよ? Ajax Memo
  第8回 HTML_QuickForm_Controller大好き!
  第9回 Mojaviのまとめ
  第10回 Ajax使ってみました
  第11回 PHPEclipse開発環境設定
  第12回 Eclipse+PHPIDEインストール記
  第13回目 PHPIDEによるデバック
  第14回目 Selenium IDEを使ってみました
  第15回目 PDT(旧 PHPIDE)のインストール、デバック