人気ブログランキング |
(PHP)Smarty利用時に入力チェックエラー時に入力画面に戻し入力データを再表示する方法

フォームの入力でチェックをした後どうするかについて、
 エラー画面に遷移しエラー表示→入力画面に戻す(戻るボタンで戻ってもらう)
という方法と、
 入力画面に戻しエラー表示
という2パターンがあると思います。
(まぁAjax使ってたりすると、JavaScript内でチェックかけてPHP側行く前の入力画面の段階でDOMを使ってエラー表示する方法ができるんですが。。。)

今回やろうとしてるのは後者の方法です。
なぜなら、前者だと作るのは楽ですが、ユーザビリティを考えると後者の方が利点があります。

しかし、ここで問題になってくるのが、入力画面に戻った時にユーザの入力内容をどう再表示するかということです。

とりあえず、入力チェックエラー後に、エラー画面ではなく入力画面を再表示する場合のSmartyテンプレートの書き方例 を参考にして書いてみました。


概要として、PDOを使ってSQLiteから表示項目を取得して入力ページを表示。入力チェックでNGなら、入力ページに戻し、エラーを表示するというものです。
<?php
session_start();
 
try {
// DBに接続する
$db = new PDO( 'sqlite2:./test.sqlite', '', '' );
/* ..... DBアクセス ..... */
//項目取得
$dbRes_product = $db->query( 'SELECT * FROM product ORDER BY id' )->fetchAll();
$dbRes_questionnaires = $db->query( 'SELECT * FROM questionnaires ORDER BY id' )->fetchAll();
// DBから切断する ( $db = null; も可能)
unset( $db );
} catch( PDOException $ex ) {
// DBアクセスができなかったとき
print 'アクセスできません : ' . $ex->getMessage();
unset( $db );
die();
}
//Smarty読み込み(ドキュメントルート外のSmartyクラスにアクセス)
require_once('./smarty/libs/Smarty.class.php');
//Smartyオブジェクト作成
$smarty = new Smarty();
//Smartyのディレクトリ設定(キャッシュやテンプレート置き場など)
$smarty->template_dir = "./smarty/templates";
$smarty->compile_dir = "./smarty/templates_c";
$smarty->cache_dir ="./smarty/cache";
//エスケープ
$smarty->default_modifiers = array('escape','nl2br');
 
//$_SESSION['postdata']にユーザが入力したデータがあるのでそれをアサイン
if( isset($_SESSION['postdata'])){
$smarty->assign("q", $_SESSION['postdata'] );
}else{
$smarty->assign("q", array());
}
//エラー情報アサイン
if( isset($_SESSION['err_info'])){
$smarty->assign("err", $_SESSION['err_info'] );
}else{
$smarty->assign("err", array());
}
 
$smarty->assign("product", $dbRes_product);
$smarty->assign("questionnaires", $dbRes_questionnaires);
 
//テンプレート表示
$smarty->display("connect.tpl");
?>




<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head></head>
<body>
<form method="post" action="confirm.php" >
氏名(必須):
{if isset($err.name)}
エラー:{$err.name}<br>
{/if}
<input type="text" name="name" value="{if isset($q.name)}{$q.name}{else}氏名入力してください{/if}" >
<br>
製品(必須):<br>
{if isset($err.product)}
エラー:{$err.product}<br>
{/if}
{section name=iCnt loop=$product}
<input type="radio" name="product"
{if isset($q.product)
&& $q.product eq $product[iCnt].id}
checked="checked"
{/if}
value="{$product[iCnt].id}">
{$product[iCnt].value} <br>
{/section}
<br><br>
アンケート(必須。複数選択可):<br>
{if isset($err.questionnaires)}
エラー:{$err.questionnaires}<br>
{/if}
{section name=iCnt loop=$questionnaires}
<input type="checkbox" name="questionnaires[]"
{if isset($q.questionnaires)
&& is_array($q.questionnaires)
&& $questionnaires[iCnt].id|in_array:$q.questionnaires}
checked="checked"
{/if}
value="{$questionnaires[iCnt].id}">
{$questionnaires[iCnt].value} <br>
{/section}
<br><br>
<input type="submit" value="送信" name="submit">
</form>
</body></html>


(文字数制限のためハイライト無し)

<?php
session_start();

//入力チェック
InputCheck();
//okなら確認画面等に遷移。

function InputCheck(){
//セッション変数きれいに
unset($_SESSION['postdata']);
unset($_SESSION['err_info']);

//入力チェック処理
if( isset($_POST['name']) || empty($_POST['name']) ){
$errInfo['name'] = '氏名が指定されていません。';
}
if( ! isset($_POST['product']) ){
$errInfo['product'] = '項目が選択されていません。';
}
if( ! isset($_POST['questionnaires']) ){
$errInfo['questionnaires'] = '項目が選択されていません。';
}

if( count($errInfo) > 0 ){
//POSTデータ,エラー情報をセッション変数に持たす
$_SESSION['err_info'] = $errInfo;
$_SESSION['postdata'] = $_POST;
header("Location:input.php");
exit;
}
}
?>


ユーザが入力したフォームのデータをセッション変数に持たし、テンプレート内のIF文を使って、セッション変数が存在するならセットするというものですね。
テキストボックスなら、フォーム入力データを持つセッション変数内に存在すれば value にセットするだけです。
ラジオボタンは、ループ内で、データがフォーム入力データを持つセッション変数内に存在し、かつ value と同じ値ならチェックします。
複数選択できるチェックボックスは、ラジオボタンとほぼ同様ですが、is_array,in_array を使うのがみそです。

エラー情報も同様に、テンプレート内のIF文でデータがあれば表示します。

まぁたしかに、テンプレート内に条件分岐を入れるのは余りきれいなやり方ではないですが、それ以外にいい方法も思いつかなかったので。。。。
by jehoshaphat | 2011-07-03 01:02 | PHP開発


<< (PHP)曜日を取得する (PHP)フォームからPOST... >>