追加ボタンでフォームを増やしていく(表の処理)
実装概要
動的にフォームを追加していくという実装を紹介ます。今回は、表側の実装だけにとどまります。今回は、3つの例を作ってみました。一つ目はテキストフォームを2つ追加するもの。2つ目は、テキストフォームと画像選択フォーム、3つ目は、2つ目と機能的には同じですが、選択したものをアップロード前に、プレビューするというものです。実装は、jQueryを使いますので、読み込みが必要です。
フォームの追加 テキスト&テキスト
追加ボタンを押すと$(‘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>
フォームの追加 テキスト&画像(アップロード前プレビューなし)
こちらの実装も、はじめに紹介した、テキストフォームと同様となっています。唯一異なる点は、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>
フォームの追加 テキスト&画像(アップロード前プレビューあり)
テキスト部分は、上記と同じですので、説明を省略します。異なる部分は、画像選択ボタンに関連するコードの部分です。画像のプレビュー部分では、追加ボタンを押すたびに、フォームが生成され、それに付随する形で、画像をプレビューを表すために定義した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データを元に、データベースへの登録を行います。画像の場合は、データベースの登録+保存先フォルダの作成・アップロード・リサイズ等の処理が必要になります。また、これらを一覧する画面や、編集画面も必要となってきますので、今回よりは、若干複雑な処理になってきます。こちらは、次回に、紹介しようと思います。おそらく長くなるので、データーベース挿入編と、データベース更新編にでも分けてサンプルを作ろうかと思います。