追加ボタンでフォームを増やしていく(表の処理)
実装概要
動的にフォームを追加していくという実装を紹介ます。今回は、表側の実装だけにとどまります。今回は、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データを元に、データベースへの登録を行います。画像の場合は、データベースの登録+保存先フォルダの作成・アップロード・リサイズ等の処理が必要になります。また、これらを一覧する画面や、編集画面も必要となってきますので、今回よりは、若干複雑な処理になってきます。こちらは、次回に、紹介しようと思います。おそらく長くなるので、データーベース挿入編と、データベース更新編にでも分けてサンプルを作ろうかと思います。