PAGE TOP


追加ボタンで画像フォームを増やしていく(uploadThumbs.jsの利用編)

2017年7月11日Javascript, PHP

実装概要

過去3回にわたって、追加ボタンで画像フォームを増やしていく実装をやってきました。過去3回では、画像を選択した時点でアップロードする前にプレビューを表示する実装を実際にコードを書いて実現していました。今回は、その部分についてのコードは書かずにプラグインを使用して、uploadThumbs.jsを使用して実現してみようというものです。プレビューを表示するということに関しては、とても簡単にオプションを設定することで実現可能です。しかし、実際、uploadThumbs.jsの中身をみてみても分かるように、実装に余分なコードがありすぎて、とても効率的だとは思えません。いらない部分は削除してもよいです。プラグインを使うとどういう実装になるのかというのを実際に確かめたいと思います。

前回参考
2017.7.4 追加ボタンでフォームを増やしていく(表の処理)
2017.7.9 追加ボタンで画像フォームを増やしていく(データベース挿入・表示)
2017.7.10 追加ボタンで画像フォームを増やしていく(編集画面・更新処理)

プラグインの基本的な使い方

プラグインを利用するには、まずは、お決まりではありますが、jquery.jsが読み込まれている必要があります。加えて、プラグインであるjquery.uploadThumbs.jsが読み込まれている必要があります。これらをヘッダーで読み込みます。
jquery.uploadThumbs.jsはGitHubよりタウンロードして任意の場所に設置して、そこから読み込んでください。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="../js/jquery.upload_thumbs.js"></script>

使い方は、下記のように指定したformのインプットの、.uploadThumbs()にプラグインで定義されているオプションを設定します。

<script type="text/javascript">
$(function() {
  $('form input:file').uploadThumbs({position : 0, imgbreak : true});
//postion: 0 …inputの前に画像を挿入する。
//imgbreak:true …画像の後に改行をいれる。
});
</script> 

オプションを指定しない場合は、inputの前に画像が挿入されます。画像挿入後に改行もされません。オプション設定なしでもカスタマイズは、htmlで十分できます。

<script type="text/javascript">
$(function() {
  $('form input:file').uploadThumbs();
});
</script> 

他にも、オプションがあるようですが、試して検証していないので、なんともいえませんが、下記は、プラグインのオプション説明です。コメントアウトの部分がオプションの説明です。

option = $.extend({
position  : 0,		// 0:before, 1:after, 2:parent.prepend, 3:parent.append,
			// any: arbitrarily jquery selector
imgbreak  : false,	// append <br> after thumbnail images
exclusion : true,	// do exclusion image control
checkbox  : ':checkbox, label, .checked_images',	// selector to find checkbox for exclusion image control
alternate : '.alt'	// selecter for alternate view input file names
}, option || {});

フォームに関しては、特に特別な実装はありません。プラグインは複数選択(multiple=”multiple”)にも対応できます。

<form action="data.php" method="post" enctype="multipart/form-data"> 
<table>
  <thead>
    <tr>
      <th>テキスト</th>
      <th>画像(1つ選択)</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>
  </tfoot>
</table>
<input type="submit" name="send" value="送信">
</form>

<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/*" multiple="multiple" /></label></td>
    </tr>
  </tbody>
  <tfoot>
  </tfoot>
</table>
<input type="submit" name="send" value="送信">
</form>

追加ボタンで画像フォームを増やしていく(追加フォーム編 index.php)

こちらの実装は、ほとんど前回のものと同じです。異なるのは画像のプレビュー部分の実装です。プラグインを利用するか、自分で定義した関数を利用するのかの違いです。特に、フォームにidをつけて、追加したフォームにもプレビューが表示されるようにしています。$(‘#file_’ + num).uploadThumbs({position : 0, imgbreak : true}); このあたりは、前回の関数に定義していた部分をまるごと、置き換えただけになります。同様に、編集画面も同様になます。

【index.php】

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>SumidaiNET TEST</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="../js/jquery.upload_thumbs.js"></script>
</head>
<body>
<style>
img{
    margin:0 5px 5px 0;
    max-width:160px;
    vertical-align:bottom;
}
</style>
<script type="text/javascript">

$(function() {
    var num = 1;
  $('#file_1').uploadThumbs({position : 0, imgbreak : true});
  $('button#add').click(function(){

    num = num + 1;
  var tr_row = '' +
  '<tr>' +
    '<td><input type="text" name="text[]"></td>' +
    '<td><label><input type="file" id="file_' + num + '" name="img[]" accept="image/*" /></label></td>' +
  '</tr>';
  $(tr_row).appendTo($('table > tbody'));
  $('#file_' + num).uploadThumbs({position : 0, imgbreak : true});
    });
});
</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" id="file_1" 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>
</body>
</html>

追加ボタンで画像フォームを増やしていく(一連の流れ)

一連のながれとは、index.phpよりデータを追加し、upload.phpで処理し、次にview.phpで表示します。又は、それらを編集する画面も必要なので、edit.phpを作ります。そこから送信されたデータは、update.phpで処理され、更新されるという流れです。処理には、テキストデータと、画像名は、データベースに記憶します。今回、この実装に関しての説明は、前回、前々回に紹介したものとほぼ同じです。従って、異なる部分だけを説明します。

今回のタウンロードサンプルは前回のサンプルを部分的に書き換えるだけなので、確認用のサンプルしか用意はしていませんので、2017.7.9 追加ボタンで画像フォームを増やしていく(データベース挿入・表示) 2017.7.10 追加ボタンで画像フォームを増やしていく(編集画面・更新処理) で公開してある2つのサンプルをダウンロードして、index.phpとedit.phpだけのhtml部分とjavascript部分だけを書き換えてください。その他の部分は同じです。index.phpの内容は、前方のトピックで紹介しましたし、eidt.phpの内容は下記に紹介します。あと、データベースのテーブルの作成も2017.7.9に投稿のものを参考にしてください。

【edit.php】

<?php
require_once("db.php");
$dbh = db_connect();
try{
   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $sql = "SELECT * FROM img_data WHERE user_id = 1 AND post_id = 1";
   $stmt = $dbh->query($sql);
   $data = $stmt->fetchAll();
}catch (PDOException $e){
   print('Error:'.$e->getMessage());
   die();
}
?>

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>SumidaiNET</title>
<script src="../js/jquery-3.2.1.min.js"></script>
<script src="../js/jquery.upload_thumbs.js"></script>
    <style type="text/css">
        img {
            margin: 0 5px 5px 0;
            max-width: 160px;
            vertical-align: bottom;
        }
    </style>
</head>
<body>
<form action="update.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1048576">
    <table>
        <thead>
        <tr>
       <th>テキスト</th>
        <th>画像</th>
        </tr>
        </thead>
        <tbody>
<?php
$num = 1;

foreach($data as $key){
  list($year, $month, $day) = preg_split('/[-: ]/', $key['date']);  
?>
        <tr  id="tr_<?=$num?>">
            <td><input type="text" name="text[]" value="<?=$key['text']?>"></td>
            <td id="td_<?=$num?>">
                <div id="view_<?=$num?>"></div>
                <?php if(!empty($key['img'])){ ?>
                <a href="http://sample.com/img_full/<?=$year ?>/<?=$month ?>/<?=$day?>/f<?=$key['img']?>"><img id="img_<?=$num?>" src="http://sample.com/img_med/<?=$year ?>/<?=$month ?>/<?=$day?>/m<?=$key['img']?>"/></a><br>
                <button class="del" rel= "<?=$year ?>/<?=$month ?>/<?=$day?>/<?=$key['img']?>"type="button">イメージ削除</button>
                <button class="del_line" rel= "<?=$year ?>/<?=$month ?>/<?=$day?>/<?=$key['img']?>/<?=$key['ID']?>"type="button">行削除</button>
                <?php } ?>
                <input type="file" id="file_<?=$num?>" name="img[]" accept="image/*" <?php if(!empty($key['img'])){ ?>style="display: none"<?php } ?>  >
                <input type="hidden" name="ID[]" value="<?=$key['ID']?>">
            </td>
        </tr>
<?php 
  $num ++;
} ?>
        </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>

<?php if(!empty($data[0]['ID'])){ ?>
<p><button type="button" onclick="location.href='del_b.php'">全て削除する</button></p>
<?php } ?>

<script type="text/javascript">
$(function () {

   var num = <?=$num -1 ?>;
   var count = document.querySelectorAll("td[id]").length;
   $(':hidden[name="row_length"]').val(count);
   var view_count = document.querySelectorAll("div[id]").length;

  //イメージ削除
  $("button.del").click(function(){
    var td = $(this).parent().attr('id');
    td = td.split("_");
    var data = $(this).attr('rel');
    data = data.split("/");
    $(this).replaceWith();

     $.ajax({
        url: 'del_img.php',
        type: 'POST',
        data:{ year:data[0],month:data[1],day:data[2],img:data[3] },
        timeout: 10000,
        dataType: 'text'
        })
      .done(function( data ) {
        $('#img_' + td[1]).parent().next().replaceWith();
        $('#img_' + td[1]).parent().replaceWith();
        $('#img_' + td[1]).replaceWith();
        $('#file_' + td[1]).show();
        })
      .fail(function( data ) {
        })
      .always(function( data ) {
     });

  });

  //テキスト・イメージ削除
  $("button.del_line").click(function(){
    var td = $(this).parent().attr('id');
    td = td.split("_");
    var data = $(this).attr('rel');
    data = data.split("/");
    $(this).replaceWith();

     $.ajax({
        url: 'del_line.php',
        type: 'POST',
        data:{ year:data[0],month:data[1],day:data[2],img:data[3],ID:data[4] },
        timeout: 10000,
        dataType: 'text'
        })
      .done(function( data ) {
        $('#tr_' + td[1]).replaceWith();
        })
      .fail(function( data ) {
        })
      .always(function( data ) {
     });

  });

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

      if(view_count ===5 ){
         $('#message').html('※ 追加フォームは' + view_count + 'つまでです。<br>');
       }else{
         count = count + 1;
         view_count = view_count + 1;
         var tr_row = '' +
           '<tr>' +
           '<td><input type="text" name="text[]"></td>' +
           '<td><div  id="view_' + count + '"></div><input type="file" id="file_' + count + '" name="img[]" accept="image/*" /></td>' +
           '</tr>';
       $(tr_row).appendTo($('table > tbody'));
       $('#reload').html('<input type="button" value="リロードする" onclick="window.location.reload();" /><br>');
       $('#file_' + count).uploadThumbs({position : 0, imgbreak : true});
      }
  });

  for(var i = 1; i <= <?=$num -1 ?>; i++) {
       $('#file_' + i).uploadThumbs({position : 0, imgbreak : true});
  }

});
</script>
</body>
</html>