PHP実習 (04) 入力フォームの確認を表示 2

PHP実習 (04) 入力フォームの確認を表示 2

*解答はHTMLコード、HTML&PHPコードと書かれたところをクリックすると表示されます。

問題 次のサンプルのように「PHP実習 (3)入力フォームで入力されたデータを確認付きで表示」を変更して、確認画面から入力フォームに戻ってもデータを保持するようにしましょう。
サンプル ここでは入力フォームをPHPにしてセッションで保存したデータを受け取れるようにします。
HTML&PHPコードフォーム
<?php
session_start();
?>
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>フォームサンプル</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
<style type="text/css">
#formTable {
  border: 1px solid #666;
  border-collapse: collapse;
  margin: auto;
  background-color: #fff;
}
tr, td {
  border: 1px solid #666;
  border-collapse: collapse;
  padding:5px;
}
th {
  background-color: #CCC;
}
#form1 #formButton {
  text-align: center;
}
</style>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script type="text/javascript">
function clearFormAll() {
    for (var i=0; i<document.forms.length; ++i) {
        clearForm(document.forms[i]);
    }
}
function clearForm(form) {
    for(var i=0; i<form.elements.length; ++i) {
        clearElement(form.elements[i]);
    }
}
function clearElement(element) {
    switch(element.type) {
        case "submit":
        case "button":
            return;
        case "text":
        case "textarea":
            element.value = "";
            return;
        case "checkbox":
        case "radio":
            element.checked = false;
            return;
        case "select-one":
        case "select-multiple":
            element.selectedIndex = 0;
            return;
        default:
    }
}
</script>
</head>
<body>
<header>
  <div class="inner">
    <h1>フォーム Sample</h1>
  </div>
</header>
<article>
  <form name="form1" id="form1" method="post" action="sample3a.php">
    <table cellpadding="0" cellspacing="0" summary="お問い合わせフォーム" id="formTable">
      <caption>
      お問い合わせフォーム
      </caption>
      <tr>
        <th><label for="subject">お問い合わせ内容</label></th>
        <td><select name="subject" id="subject">
          <?php
    $sub = array('選択してください','予約について','メニューについて');
    foreach ($sub as  $val) {
             print('<option value="'.$val.'"');
       if ($val == $_SESSION['subject']) {
         print(' selected="selected">'.$val.'</option>');
       }else{
              print('>'.$val.'</option>');
       }
  } ?>
          </select></td>
      </tr>      
      <tr>
        <th><label for="name">お名前</label></th>
        <td><input type="text" name="name" id="name" value="<?php print($_SESSION['name']); ?>" size="20" /></td>
      </tr>
      <tr>
        <th><label for="tel">電話番号</label></th>
        <td><input type="text" name="tel" id="tel" value="<?php print($_SESSION['tel']); ?>" size="20" /></td>
      </tr>
      <tr>
        <th><label for="email">メールアドレス</label></th>
        <td><input type="text" name="email" id="email" value="<?php print($_SESSION['email']); ?>" size="20" /></td>
      </tr>
      <tr>
        <th>ご連絡方法</th>
        <td>
          <?php
    $tools = array('メール', '電話');
    foreach ($tools as $tool) {
      print('<label>');
      print('<input type="radio" name="contact" value="'.$tool.'"');
      if ($contact == $_SESSION['メール']) { print(' checked'); }
      print(' />');
      print($tool.'&ensp;</label>');
    }
    ?></td>
      </tr>
      <tr>
        <th>当店を何でお知りになりましたか</th>
        <td id="checkBoxData">
        <?php
    $whats = array('magazine'=>'雑誌','web'=>'ホームページ','friend'=>'友人・知人','signboard'=>'看板','etc'=>'その他');
   
    foreach ($whats as $k_what => $v_what) {
      print('<label>');
      print('<input type="checkbox" name="what[]" value="'.$k_what.'"');
      if (isset($_SESSION['what']) === TRUE) {
        foreach ($_SESSION['what'] as $what) {
          if ($k_what === $what) { print(' checked'); }
        }
      }
      print(' />');
      print($v_what.'</label></br>');
    }
    ?>
      </td>
      </tr>
      <tr>
        <th><label for="free">自由記入欄</label></th>
        <td><textarea name="free" id="free" cols="25" rows="5"><?php print($_SESSION['free']); ?></textarea>
          <p class="notes">※ご予約の場合は、希望日時をご記入ください。</p></td>
      </tr>
    </table>
    <div id="formButton">
      <input type="submit" name="submit" id="submit" value="送信" />
      <input type="button" name="reset" id="reset" value="リセット" onClick="clearFormAll();" />
    </div>
  </form>
</article>
<footer> <small>All rights reserved STUDIO.M 2014</small> 
  <!-- footer --></footer>
</body>
</html>
HTML&PHPコード(確認ファイル)
<?php
session_start();
if (isset($_POST['name']) === TRUE) { $_SESSION['name'] = $_POST['name']; }
if (isset($_POST['tel']) === TRUE) { $_SESSION['tel'] = $_POST['tel']; }
if (isset($_POST['email']) === TRUE) { $_SESSION['email'] = $_POST['email']; }
if (isset($_POST['contact']) === TRUE) { $_SESSION['contact'] = $_POST['contact']; }
if (isset($_POST['subject']) === TRUE) { $_SESSION['subject'] = $_POST['subject']; }
if (isset($_POST['free']) === TRUE) { $_SESSION['free'] = $_POST['free']; }
if (isset($_POST['what']) === TRUE) { $_SESSION['what'] = $_POST['what']; }
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>sample</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
</head>
<body>
<header>
  <div class="inner">
    <h1>フォーム Sample</h1>
  </div>
</header>
  <article>
    <h2>フォーム入力内容</h2>
    <section>
      <p>
        <?php
    $name = htmlspecialchars($_POST['name'], ENT_QUOTES);
    $tel = htmlspecialchars($_POST['tel'], ENT_QUOTES);
    $email = htmlspecialchars($_POST['email'], ENT_QUOTES);
    $contact = htmlspecialchars($_POST['contact'], ENT_QUOTES);
    $subject = htmlspecialchars($_POST['subject'], ENT_QUOTES);
    $free = htmlspecialchars($_POST['free'], ENT_QUOTES);
    echo "<br>お問い合わせ内容:".$subject.
      "<br>名前:".$name.
      "<br>電話番号:".$tel.
      "<br>メールアドレス:".$email.
      "<br>連絡方法:".$contact.
      "<br>当店を何でお知りになりましたか:";
    foreach($_POST['what'] as $what){
      print(htmlspecialchars($what, ENT_QUOTES)."、");
    }
    echo "<br>自由記入欄:".$free;
    ?>
      </p>
      <p><a href="sample3.php">戻る</a> | <a href="sample_end2.php">次へ</a></p>
    </section>
  </article>
  <footer> <small>All rights reserved STUDIO.M 2014</small> </footer>

</body>
</html>

HTML&PHPコード(最終表示ファイル)
<?php
session_start();
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>sample</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
</head>
<body>
<header>
  <div class="inner">
    <h1>フォーム Sample</h1>
  </div>
</header>
  <article>
    <h2>フォーム入力内容</h2>
    <section>
      <p>
        <?php
    $name = htmlspecialchars($_SESSION['name'], ENT_QUOTES);
    $tel = htmlspecialchars($_SESSION['tel'], ENT_QUOTES);
    $email = htmlspecialchars($_SESSION['email'], ENT_QUOTES);
    $contact = htmlspecialchars($_SESSION['contact'], ENT_QUOTES);
    $subject = htmlspecialchars($_SESSION['subject'], ENT_QUOTES);
    $free = htmlspecialchars($_SESSION['free'], ENT_QUOTES);
    echo "<br>お問い合わせ内容:".$subject.
      "<br>名前:".$name.
      "<br>電話番号:".$tel.
      "<br>メールアドレス:".$email.
      "<br>連絡方法:".$contact.
      "<br>当店を何でお知りになりましたか:";
    foreach($_SESSION['what'] as $what){
      print(htmlspecialchars($what, ENT_QUOTES)."、");
    }
    echo "<br>自由記入欄:".$free;
    ?>
      </p>
    </section>
  </article>
  <footer> <small>All rights reserved STUDIO.M 2014</small> </footer>
<?php session_unset(); ?>
</body>
</html>

解説

セッションを利用することでフォームで入力されたデータをページを跨いで保存できます。
けれども、確認のページから入力フォームに戻ると全てのデータはクリアされてしまいます。
この実習ではこの間もデータが保持されるような仕組みを作ることがねらいです。
とはいえ、セッションを利用している以上データはページを跨いで保管されています。
ということは、入力フォームで保管されたデータを受け取る仕組みを作ればよいことになります。
そこで入力フォームもPHPファイルにしてしまいます。

  1. session_start()関数でセッションを開始
  2. 次にフォームの部品の値にセッションの値を格納します。
    次のようにして値をいれます。
    value="<?php print($_SESSION['name']); ?>" 
    
  3. セレクトメニューやラジオボタン、チェックボックスはforeach文を使用して配列のデータを取り出します。
  4. その他のファイルは特に編集の必要はありませんが、確認ページの戻るをクリックしたら今作成したphpファイルにリンクを変更するだけです。最終ページの変更はありません。

さて、ここで問題になるのが入力フォームのリセットボタンです。input type=”reset”を使用してもそれはリセットされるだけで、valueの値にセッションの値が代入されてしまいます。
そのため、リセットの役割を果たせなくなるのです。

ここではリセットではなくjavascriptの値は「無し」を代入することで対応しています。
onClick=”clearFormAll()”としてイベントハンドラを仕掛けておきます。
clearFormAll()は入れ子状態で2つの関数を呼び出し、DOMを操作してそれぞれの入力boxの値を空白にします。
for文でDOMを使って得たform内の要素のtype属性をswich文で判定してそれぞれの値に見合った空白状態、あるいは選択なしの状態を作り出しています。

function clearFormAll() {
    for (var i=0; i<document.forms.length; ++i) {
        clearForm(document.forms[i]);
    }
}
function clearForm(form) {
    for(var i=0; i<form.elements.length; ++i) {
        clearElement(form.elements[i]);
    }
}
function clearElement(element) {
    switch(element.type) {
        case "submit":
        case "button":
            return;
        case "text":
        case "textarea":
            element.value = "";
            return;
        case "checkbox":
        case "radio":
            element.checked = false;
            return;
        case "select-one":
        case "select-multiple":
            element.selectedIndex = 0;
            return;
        default:
    }
}