PAGE TOP


追加ボタンでフォームを増やしていく(表の処理)

2017年7月4日Javascript

実装概要

動的にフォームを追加していくという実装を紹介ます。今回は、表側の実装だけにとどまります。今回は、3つの例を作ってみました。一つ目はテキストフォームを2つ追加するもの。2つ目は、テキストフォームと画像選択フォーム、3つ目は、2つ目と機能的には同じですが、選択したものをアップロード前に、プレビューするというものです。実装は、jQueryを使いますので、読み込みが必要です。

フォームの追加 テキスト&テキスト

フォームの追加 テキスト&テキスト 敦賀市 WEBシステム開発 すみだいねっと

追加ボタンを押すと$(‘button#add’).click(function(){});の中に書いたコードが実行されます。テーブルタグの中に追加する、htmlを格納した、tr_form変数を、.appendTo()に設定した、タグの後に追加するようにします。これだけで、追加フォームが動的に追加されるようになります。

このように、フォームを追加する際に、必ず登場するのが、name=”text_[]”のような名前の付け方です。送信するフォームのnameの最後に空の角括弧 “[]” を追加することです。これにより、POST送信後には自動で、0からの添え字をつけてもらえます。正確には、例えば、既に、添え字に、[12]など設定してある場合は、次のフォームの[]は、[13]になります。最大値に+1してくれます。値が設定していない場合は、0からスタートということです。

【index.html】

<script type="text/javascript">

$(function() {

  $('button#add').click(function(){

  var tr_form = '' +
  '<tr>' +
    '<td><input type="text" name="text_1[]"></td>' +
    '<td><input type="text" name="text_2[]"></td>' +
  '</tr>';

  $(tr_form).appendTo($('table > tbody'));

});


});
</script> 

<form action="data.php" method="post" enctype="multipart/form-data"> 
<table>
  <thead>
    <tr>
      <th>材料</th>
      <th>数量</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><input type="text" name="text_1[]"></td>
      <td><input type="text" name="text_2[]"></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td ><button id="add" type="button">追加</button></td>
    </tr>
  </tfoot>
</table>
<input type="submit" name="send" value="送信">
</form>

フォームの追加 テキスト&画像(アップロード前プレビューなし)

フォームの追加 テキスト&画像(アップロード前プレビューなし) 敦賀市 WEBシステム開発 すみだいねっと

こちらの実装も、はじめに紹介した、テキストフォームと同様となっています。唯一異なる点は、2番目のinputがテキスト入力フォームではなく、画像選択フォームだということです。こちらも、同様に追加ボタンを押すと、ボタンに設定した処理内容が、jqueryで追加されていくという仕組みになっており、処理場も同じになっています。

<script type="text/javascript">

$(function() {

  $('button#add').click(function(){

  var tr_form = '' +
  '<tr>' +
    '<td><input type="text" name="text[]"></td>' +
    '<td><label><input type="file" name="img[]" accept="image/*" /></label></td>' +
  '</tr>';

  $(tr_form).appendTo($('table > tbody'));


});


});
</script> 

<form action="data.php" method="post" enctype="multipart/form-data"> 
<table>
  <thead>
    <tr>
      <th>テキスト</th>
      <th>画像</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><input type="text" name="text[]"></td>
      <td><label><input type="file" name="img[]" accept="image/*" /></label></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td ><button id="add" type="button">追加</button></td>
    </tr>
  </tfoot>
</table>
<input type="submit" name="send" value="送信">
</form>

フォームの追加 テキスト&画像(アップロード前プレビューあり)

フォームの追加 テキスト&画像(アップロード前プレビューあり) 敦賀市 WEBシステム開発 すみだいねっと

テキスト部分は、上記と同じですので、説明を省略します。異なる部分は、画像選択ボタンに関連するコードの部分です。画像のプレビュー部分では、追加ボタンを押すたびに、フォームが生成され、それに付随する形で、画像をプレビューを表すために定義したimgView関数が、実行されます。それぞれのフォームにアクションがあった場合、new FileReader()でFileReaderオブジェクトをインスタンス化し、選択した画像がimgタグに読み込まれ、空の<div id=”view_x”></div>の内部に書き換えられます。その他の変更箇所は、フォームが5つまでしか追加できなくした部分です。この部分は、画像が表示されている場合、id=view_~ が存在するため、それらをカウントして、追加ボタンを押した際に、条件分岐により、view_count ===5 の場合は、id=”message” の部分に、メッセージが表示されるようにしています。

【index.html】

<style>
img{
    margin:0 5px 5px 0;
    max-width:160px;
    vertical-align:bottom;
}
</style>

<script type="text/javascript">
$(function () {
        var num = 1;
        var view_count = document.querySelectorAll("div[id]").length;

        function imgView(n) {
            var reader = new FileReader();
            document.getElementById('file_' + n).onchange = function (e) {
                reader.addEventListener('load', function (e) {
                    $('#view_' + n).html('<img src="' + e.target.result + '" />');
                });
                reader.readAsDataURL(this.files[0]);
            }

        }

        imgView(num);

        $('button#add').click(function () {

          if(view_count ===5 ){
              $('#message').html('※ 追加フォームは' + view_count + 'つまでです。<br>');
            }else{

            num = num + 1;
            view_count = view_count + 1;

              var tr_form = '' +
                  '<tr>' +
                  '<td><input type="text" name="text[]"></td>' +
                  '<td><div  id="view_' + num + '"></div><input type="file" id="file_' + num + '" name="img[]" accept="image/*" /></td>' +
                  '</tr>';
              $(tr_form).appendTo($('table > tbody'));
              $('#reload').html('<input type="button" value="リロードする" onclick="window.location.reload();" /><br>');

              imgView(num);
          }
        });

});
</script>

<form action="data.php" method="post" enctype="multipart/form-data">
    <table>
        <thead>
        <tr>
       <th>テキスト</th>
        <th>画像</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <td><input type="text" name="text[]"></td>
            <td>
                <div id="view_1"></div>
                <input type="file" id="file_1" name="img[]" accept="image/*">
            </td>
        </tr>
        </tbody>
        <tfoot>
        <tr>
            <td>
                <button id="add" type="button">追加</button><span id="reload"></span>
            </td>
        </tr>
        </tfoot>
    </table>
    <span id="message"></span>
    <input type="submit" name="send" value="送信">
</form>

感想

今回は、表側の実装だけを紹介していす。実際は、フォームでの追加情報は、データベースで管理していく形になると思います。
今回の紹介したフォームのPOST先では、全て、$_POSTの中身を print_r()で表示させたものになりますが、実際は、実用的に使うには、POSTデータを元に、データベースへの登録を行います。画像の場合は、データベースの登録+保存先フォルダの作成・アップロード・リサイズ等の処理が必要になります。また、これらを一覧する画面や、編集画面も必要となってきますので、今回よりは、若干複雑な処理になってきます。こちらは、次回に、紹介しようと思います。おそらく長くなるので、データーベース挿入編と、データベース更新編にでも分けてサンプルを作ろうかと思います。

続編 2017.7.9 追加ボタンで画像フォームを増やしていく(データベース挿入・表示)