Smarty と HTML_QuickForm の今までの応用で少し大きめのフォームを作成してみます。
必要なファイルは以下の4つです。
addGroupRule で numeric 指定すると必須入力になるようです。
必須入力を回避させるために regex で正規表現のルールを作成しました。
今回は javascript での検証は行わず、サーバーサイドでのみ入力値チェックを行っています。
<?php // /var/www/html/FourthStepQuickForm.php require_once "HTML/QuickForm.php"; require_once "HTML/QuickForm/Renderer/ArraySmarty.php"; class FourthStepQuickForm { var $_form; // コンストラクタ($argAction :「送信」ボタンのリンク先) HTML_QuickForm オブジェクトを生成 function FourthStepQuickForm($argAction) { $this->_form = new HTML_QuickForm('fourthForm', 'post', $argAction); $this->_form->_requiredNote = '<span style="color:#ff0000;">*</span> 必須入力'; } // フォームに要素を追加 function setItem() { // お名前 $this->_form->addElement('text', 'name', 'お名前', array('id' => 'name', 'size' => 50, 'maxlength' => 30)); $this->_form->addElement('text', 'namekana', 'お名前(かな)', array('id' => 'namekana', 'size' => 50, 'maxlength' => 30)); // email $this->_form->addElement('text', 'email', 'e-mail', array('id' => 'email', 'size' => 50, 'maxlength' => 30)); $this->_form->addElement('text', 'email2', 'e-mail確認', array('id' => 'email2', 'size' => 50, 'maxlength' => 30)); // 郵便番号のグループ $zipArray[] = &HTML_QuickForm::createElement('text', 0, null, array('id' => 'zip0', 'size' => 6, 'maxlength' => 3)); $zipArray[] = &HTML_QuickForm::createElement('text', 1, null, array('id' => 'zip1', 'size' => 8, 'maxlength' => 4)); $this->_form->addGroup($zipArray, 'zip', '郵便番号', ' - '); // 都道府県 $areaArray = array( "北海道"=>"北海道", "青森県"=>"青森県", "岩手県"=>"岩手県", "宮城県"=>"宮城県", "秋田県"=>"秋田県", "山形県"=>"山形県", "福島県"=>"福島県", "茨城県"=>"茨城県", "栃木県"=>"栃木県", "群馬県"=>"群馬県", "埼玉県"=>"埼玉県", "千葉県"=>"千葉県", "東京都"=>"東京都", "神奈川県"=>"神奈川県", "新潟県"=>"新潟県", "富山県"=>"富山県", "石川県"=>"石川県", "福井県"=>"福井県", "山梨県"=>"山梨県", "長野県"=>"長野県", "岐阜県"=>"岐阜県", "静岡県"=>"静岡県", "愛知県"=>"愛知県", "三重県"=>"三重県", "滋賀県"=>"滋賀県", "京都府"=>"京都府", "大阪府"=>"大阪府", "兵庫県"=>"兵庫県", "奈良県"=>"奈良県", "和歌山県"=>"和歌山県", "鳥取県"=>"鳥取県", "島根県"=>"島根県", "岡山県"=>"岡山県", "広島県"=>"広島県", "山口県"=>"山口県", "徳島県"=>"徳島県", "香川県"=>"香川県", "愛媛県"=>"愛媛県", "高知県"=>"高知県", "福岡県"=>"福岡県", "佐賀県"=>"佐賀県", "長崎県"=>"長崎県", "熊本県"=>"熊本県", "大分県"=>"大分県", "宮崎県"=>"宮崎県", "鹿児島県"=>"鹿児島県", "沖縄県"=>"沖縄県"); $this->_form->addElement('select', 'area', '都道府県', $areaArray, 'id = area'); // 住所 $this->_form->addElement('text', 'place', '住所', array('id' => 'place', 'size' => 50, 'maxlength' => 50)); $this->_form->addElement('text', 'place2', '番地・マンション名', array('id' => 'place2', 'size' => 50, 'maxlength' => 50)); // 電話番号のグループ $phoneArray[] = &HTML_QuickForm::createElement('text', 0, null, array('id' => 'phone0', 'size' => 10, 'maxlength' => 5)); $phoneArray[] = &HTML_QuickForm::createElement('text', 1, null, array('id' => 'phone1', 'size' => 10, 'maxlength' => 5)); $phoneArray[] = &HTML_QuickForm::createElement('text', 2, null, array('id' => 'phone2', 'size' => 10, 'maxlength' => 5)); $this->_form->addGroup($phoneArray, 'phone', '電話番号', ' - '); // 性別のグループ $sexArray[] = &HTML_QuickForm::createElement('radio', null, null, '女性', '女性'); $sexArray[] = &HTML_QuickForm::createElement('radio', null, null, '男性', '男性'); $this->_form->addGroup($sexArray, 'sex', '性別', ' '); // 開発言語のグループ $langArray[] = &HTML_QuickForm::createElement('checkbox', 'c', null, 'C言語'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'vb', null, 'VB'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'php', null, 'PHP'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'perl', null, 'perl'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'ruby', null, 'ruby'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'python', null, 'python'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'java', null, 'java'); $langArray[] = &HTML_QuickForm::createElement('checkbox', 'cobol', null, 'COBOL'); $this->_form->addGroup($langArray, 'lang', '好きな間発言語', ' '); // テキストエリア $this->_form->addElement('textarea', 'content', 'お問い合わせ', array('id' => 'content', 'cols' => 60, 'rows' => 10)); } // フォーム要素に検証ルールを追加 function setRule() { // フィルターの適用 $this->_form->applyFilter('__ALL__','trim'); // addRule $this->_form->addRule('name', 'お名前を入力してください', 'required', null, 'server'); $this->_form->addRule('email', 'e-mailを入力してください', 'required', null, 'server'); $this->_form->addRule('email', 'e-mailが不正です。半角英数字で入力してください', 'email', null, 'server'); $this->_form->addRule('email2', 'e-mail確認を入力してください', 'required', null, 'server'); $this->_form->addRule('email2', 'e-mail確認が不正です。半角英数字で入力してください', 'email', null, 'server'); $this->_form->addRule(array('email','email2'), 'e-mailとe-mail確認が一致しません', 'compare', null, 'server'); // addGroupRule $this->_form->addGroupRule('zip', '半角数字を入力してください', 'regex', '/^\d*$/', 'server'); // numeric 指定すると必須入力になります。 $this->_form->addGroupRule('phone', '半角数字を入力してください', 'regex', '/^\d*$/', 'server'); // numeric 指定すると必須入力になります。 $this->_form->addGroupRule('lang', '2つ以上選択してください', 'required', null, 2, 'server'); // howmany パラメータで入力個数を指定しています。 } // 「確認」ボタン(入力画面)($argBtnName : ボタンの名前) function setSubmit($argBtnName) { $buttons[] = &HTML_QuickForm::createElement( 'submit', $argBtnName, '確認' ); $this->_form->addGroup($buttons, "SUBMIT_BOTTONS", null, ' '); } // 「戻る」、「送信」ボタン(確認画面)($argRtnName: 「戻る」ボタンの名前、 $argSubmitName : 「送信」ボタンの名前) function setReturnSubmit($argRtnName, $argSubmitName) { $buttons[] = &HTML_QuickForm::createElement( 'submit', $argRtnName, '戻る' ); $buttons[] = &HTML_QuickForm::createElement( 'submit', $argSubmitName, '送信' ); $this->_form->addGroup($buttons, "SUBMIT_BOTTONS", null, ' '); } // 入力値を検証する function checkValidate() { return $this->_form->validate(); } // 入力値を取得する 戻り値:要素名と入力された値の連想配列 function getVals() { return $this->_form->exportValues(); } // 画面を表示する function dispForm() { $this->_form->display(); } // 画面をフリーズする(確認画面、完了画面) function freezeForm() { $this->_form->freeze(); } } ?>
文字化けを防ぐためエンコーディング指定しました。
<?php // /var/www/html/fourthstep.php require_once "./FourthStepQuickForm.php"; require_once "Smarty.class.php"; $form = new FourthStepQuickForm('fourthstep.php'); $form->setItem(); // 要素を追加 $form->setRule(); // 検証ルール設定 if ( isset($_POST['SUBMIT_BOTTONS']['SUBMIT_INDEX']) ) { // 確認画面表示 // 検証実行 if ($form->checkValidate()) { // 検証クリア時は「戻る」、「送信」ボタンを表示 $form->setReturnSubmit('RETURN_CONF', 'SUBMIT_CONF'); $form->freezeForm(); // 要素を凍結 } else { $form->setSubmit('SUBMIT_INDEX'); } } else { // 入力画面表示 $form->setSubmit('SUBMIT_INDEX'); } mb_language('ja'); //"ja"にエンコー ディング mb_internal_encoding("UTF-8"); //内部文字エンコーディングは"UTF-8" $smarty = new Smarty(); $smarty->template_dir = '/var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/templates/'; $smarty->compile_dir = '/var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/templates_c/'; $smarty->config_dir = '/var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/configs/'; $smarty->cache_dir = '/var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/cache/'; // renderer for Smarty templates の取得 $renderer =& new HTML_QuickForm_Renderer_ArraySmarty($smarty); $renderer->setRequiredTemplate('{$label}{if $required}<span class="reqmark">*</span>{/if}'); $renderer->setErrorTemplate('{if $error}<p class="error-message">{$error}</p>{/if}{$html}'); $form->_form->accept($renderer); // 表示 if ( isset($_POST['SUBMIT_BOTTONS']['SUBMIT_CONF']) ) { // 完了画面表示 if ($form->checkValidate()) { $smarty->assign('value', $form->getVals()); $smarty->display("submit.tpl"); } } else { $smarty->assign('form', $renderer->toArray()); $smarty->display("index.tpl"); } ?>
必須入力項目には自動的に*が表示されます。
checkbox と radio には要素ごとに <label> が自動的に付けられますが、その他の項目には <label> は付きません。テンプレートで書き足しています。
{* /var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/templates/index.tpl *}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Smarty + HTML_QuickForm サンプルフォーム</title>
<style type="text/css">
{literal}
body{ text-align:center;}
.content{ margin: 10px auto; width:700px;}
h1{ font-size: 1.2em; color:#336666;}
form{ text-align:left; border:1px dashed #999999; padding:20px;}
input{ font-size:1em;}
table{ border-collapse: collapse;}
th{ border:1px solid #999999; background-color:#dedede; color:#000000; font-weight:normal; padding:0.2em;}
td{ border:1px solid #999999; padding:0.2em;}
.reqnote{ font-size:0.8em; text-align:right;}
.reqmark{ color:#ff0000;}
.bottoms{ text-align:right;}
.message{ color:#ff0000;}
.error-message{ color:#ff0000; padding:0; margin:0;}
{/literal}
</style>
{$form.javascript}
</head>
<body>
<div class="content">
<h1>サンプルフォーム4</h1>
<form {$form.attributes}>
<p class="reqnote">{$form.requirednote}</p>
<table>
<tr>
<th><label for="name">{$form.name.label}</label></th>
<td>{$form.name.html}</td>
</tr>
<tr>
<th><label for="namekana">{$form.namekana.label}</label></th>
<td>{$form.namekana.html}</td>
</tr>
<tr>
<th><label for="email">{$form.email.label}</label></th>
<td>{$form.email.html}</td>
</tr>
<tr>
<th><label for="email2">{$form.email2.label}</label></th>
<td>{$form.email2.html}</td>
</tr>
<tr>
<th><label for="zip0">{$form.zip.label}</label></th>
<td>{$form.zip.html}</td>
</tr>
<tr>
<th><label for="area">{$form.area.label}</label></th>
<td>{$form.area.html}</td>
</tr>
<tr>
<th><label for="place">{$form.place.label}</label></th>
<td>{$form.place.html}</td>
</tr>
<tr>
<th><label for="place2">{$form.place2.label}</label></th>
<td>{$form.place2.html}</td>
</tr>
<tr>
<th><label for="phone0">{$form.phone.label}</label></th>
<td>{$form.phone.html}</td>
</tr>
<tr>
<th>{$form.sex.label}</th>
<td>{$form.sex.html}</td>
</tr>
<tr>
<th>{$form.lang.label}</th>
<td>{$form.lang.html}</td>
</tr>
<tr>
<th><label>{$form.content.label}</label></th>
<td>{$form.content.html}</td>
</tr>
</table>
<p class="bottoms">{$form.SUBMIT_BOTTONS.html}</p>
</form>
</div>
</body>
</html>
{* /var/www/private/Smarty_tpl/FourthStepQuickForm_tpl/templates/submit.tpl *}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Smarty + HTML_QuickForm サンプルフォーム</title>
<style type="text/css">
{literal}
body{ text-align:center;}
.content{ margin: 10px auto; width:700px;}
h1{ font-size: 1.2em; color:#336666;}
.welcome{ text-align:left; border:1px dashed #999999; padding:20px;}
.reqnote{ font-size:0.8em; text-align:right;}
.bottoms{ text-align:right;}
.message{ color:#ff0000;}
{/literal}
</style>
</head>
<body>
<div class="content">
<h1>サンプルフォーム4 送信完了</h1>
<div class="welcome">
<p>こんにちは、{$value.name}({$value.namekana})さん。<br />ようこそ QuickForm の世界へ!</p>
<p>あなたのe-mailは『{$value.email}』ですね。</p>
<p>あなたの郵便番号は『{$value.zip[0]}-{$value.zip[1]}』ですね。</p>
<p>あなたのお住まいは『{$value.area} {$value.place} {$value.place2}』ですね。</p>
<p>あなたの電話番号は『{$value.phone[0]}-{$value.phone[1]}-{$value.phone[2]}』ですね。</p>
<p>あなたの性別は『{$value.sex}』ですね。</p>
<p>あなたのお好きな言語は『
{foreach from=$value.lang item=itemval key=keyname}
{$keyname}、
{/foreach}
』ですね。</p>
<hr />
<p>{$value.content}</p>
</div>
</div>
</body>
</html>
表示結果
htmlソースコード
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <title>Smarty + HTML_QuickForm サンプルフォーム</title> <style type="text/css"> body{ text-align:center;} .content{ margin: 10px auto; width:700px;} h1{ font-size: 1.2em; color:#336666;} form{ text-align:left; border:1px dashed #999999; padding:20px;} input{ font-size:1em;} table{ border-collapse: collapse;} th{ border:1px solid #999999; background-color:#dedede; color:#000000; font-weight:normal; padding:0.2em;} td{ border:1px solid #999999; padding:0.2em;} .reqnote{ font-size:0.8em; text-align:right;} .reqmark{ color:#ff0000;} .bottoms{ text-align:right;} .message{ color:#ff0000;} .error-message{ color:#ff0000; padding:0; margin:0;} </style> </head> <body> <div class="content"> <h1>サンプルフォーム4</h1> <form action="fourthstep.php" method="post" name="fourthForm" id="fourthForm"> <p class="reqnote"><span style="color:#ff0000;">*</span> 必須入力</p> <table> <tr> <th><label for="name">お名前<span class="reqmark">*</span></label></th> <td><input id="name" size="50" maxlength="30" name="name" type="text" /></td> </tr> <tr> <th><label for="namekana">お名前(かな)</label></th> <td><input id="namekana" size="50" maxlength="30" name="namekana" type="text" /></td> </tr> <tr> <th><label for="email">e-mail<span class="reqmark">*</span></label></th> <td><input id="email" size="50" maxlength="30" name="email" type="text" /></td> </tr> <tr> <th><label for="email2">e-mail確認<span class="reqmark">*</span></label></th> <td><input id="email2" size="50" maxlength="30" name="email2" type="text" /></td> </tr> <tr> <th><label for="zip0">郵便番号</label></th> <td><input id="zip0" size="6" maxlength="3" name="zip[0]" type="text" /> - <input id="zip1" size="8" maxlength="4" name="zip[1]" type="text" /></td> </tr> <tr> <th><label for="area">都道府県</label></th> <td><select id="area" name="area"> <option value="北海道">北海道</option> <option value="青森県">青森県</option> <option value="岩手県">岩手県</option> <option value="宮城県">宮城県</option> <option value="秋田県">秋田県</option> <option value="山形県">山形県</option> <option value="福島県">福島県</option> <option value="茨城県">茨城県</option> <option value="栃木県">栃木県</option> <option value="群馬県">群馬県</option> <option value="埼玉県">埼玉県</option> <option value="千葉県">千葉県</option> <option value="東京都">東京都</option> <option value="神奈川県">神奈川県</option> <option value="新潟県">新潟県</option> <option value="富山県">富山県</option> <option value="石川県">石川県</option> <option value="福井県">福井県</option> <option value="山梨県">山梨県</option> <option value="長野県">長野県</option> <option value="岐阜県">岐阜県</option> <option value="静岡県">静岡県</option> <option value="愛知県">愛知県</option> <option value="三重県">三重県</option> <option value="滋賀県">滋賀県</option> <option value="京都府">京都府</option> <option value="大阪府">大阪府</option> <option value="兵庫県">兵庫県</option> <option value="奈良県">奈良県</option> <option value="和歌山県">和歌山県</option> <option value="鳥取県">鳥取県</option> <option value="島根県">島根県</option> <option value="岡山県">岡山県</option> <option value="広島県">広島県</option> <option value="山口県">山口県</option> <option value="徳島県">徳島県</option> <option value="香川県">香川県</option> <option value="愛媛県">愛媛県</option> <option value="高知県">高知県</option> <option value="福岡県">福岡県</option> <option value="佐賀県">佐賀県</option> <option value="長崎県">長崎県</option> <option value="熊本県">熊本県</option> <option value="大分県">大分県</option> <option value="宮崎県">宮崎県</option> <option value="鹿児島県">鹿児島県</option> <option value="沖縄県">沖縄県</option> </select></td> </tr> <tr> <th><label for="place">住所</label></th> <td><input id="place" size="50" maxlength="50" name="place" type="text" /></td> </tr> <tr> <th><label for="place2">番地・マンション名</label></th> <td><input id="place2" size="50" maxlength="50" name="place2" type="text" /></td> </tr> <tr> <th><label for="phone0">電話番号</label></th> <td><input id="phone0" size="10" maxlength="5" name="phone[0]" type="text" /> - <input id="phone1" size="10" maxlength="5" name="phone[1]" type="text" /> - <input id="phone2" size="10" maxlength="5" name="phone[2]" type="text" /></td> </tr> <tr> <th>性別</th> <td><input value="女性" type="radio" id="qf_14933d" name="sex" /><label for="qf_14933d">女性</label> <input value="男性" type="radio" id="qf_88cc73" name="sex" /><label for="qf_88cc73">男性</label></td> </tr> <tr> <th>好きな間発言語<span class="reqmark">*</span></th> <td> <input name="lang[c]" type="checkbox" value="1" id="qf_22c8a9" /><label for="qf_22c8a9">C言語</label> <input name="lang[vb]" type="checkbox" value="1" id="qf_02a540" /><label for="qf_02a540">VB</label> <input name="lang[php]" type="checkbox" value="1" id="qf_98c419" /><label for="qf_98c419">PHP</label> <input name="lang[perl]" type="checkbox" value="1" id="qf_eb6bd7" /><label for="qf_eb6bd7">perl</label> <input name="lang[ruby]" type="checkbox" value="1" id="qf_3c8a64" /><label for="qf_3c8a64">ruby</label> <input name="lang[python]" type="checkbox" value="1" id="qf_740b32" /><label for="qf_740b32">python</label> <input name="lang[java]" type="checkbox" value="1" id="qf_5c45b4" /><label for="qf_5c45b4">java</label> <input name="lang[cobol]" type="checkbox" value="1" id="qf_f43258" /><label for="qf_f43258">COBOL</label></td> </tr> <tr> <th><label>お問い合わせ</label></th> <td><textarea id="content" cols="60" rows="10" name="content"></textarea></td> </tr> </table> <p class="bottoms"><input name="SUBMIT_BOTTONS[SUBMIT_INDEX]" value="確認" type="submit" /></p> </form> </div> </body> </html>
入力画面
エラー表示画面
確認画面
送信完了画面
投稿日: