ドラッグ&ドロップでajaxファイルアップロード html,js,css

ajaxファイルアップロードとドラッグ&ドロップ javascript

フォームにファイルアップロード機能を付け、更にそれをDrag&Dropで。しかもドロップした瞬間にアップロード始めたい(ajax)と思い他のサイトを参考にしながら作ってみました。具体的なサンプルを書いたので、コピペで動くと思います。
jQuery使っているので、使わない人はそこを置き換えればOKだと思います。

スポンサーリンク

1.フォームでなくて良い

フォーム内でなくても良いです。大まかな流れは下記

  1. ドロップエリア(div class=”droparea”)を用意
  2. ファイルをドラッグ&ドロップ
  3. divのドロップイベントでファイルを取得
  4. フォームデータを作成 let fd = new FormData();
  5. fd.append(file)、その他パラメータを同じようにセット
  6. ajaxでデータ送る

2. HTML、cssはシンプルでOK

divの入れ物とその中にinputを入れておきましょう。

HTMLは下記にしました。ddareaなdivを大枠とし、input、div.dropareaを置いています。

<div class="ddarea" data-id="<?php echo $target_id;?>">;
  <input type="file" name="file" class="inputfile">
  <div class="droparea">
    <p>;ここにファイルをドラッグ&ドロップするか、クリックしてファイルを選択</p>
  </div>
</div>

対応するCSS。これで、600×200のdropareaが出来ました。inputは非表示にしておきます。

<style type="text/css">
div.droparea {
 width: 600px;
 height: 200px;
 border: 2px solid #gray;
 border-radius: 6px;
 text-align: center;
 overflow: auto;
}
div.droparea:hover {
  cursor: pointer;
}
div.droparea p {
 text-align: center;
}

input.inputfile {
 display: none;
}

</style>

3. javascript (ajax upload以外)

必要なのは、ドラッグ&ドロップしてきた時のイベント制御です。
注意点としては、ドロップエリア以外に間違ってファイルをドロップすると、そのファイルをブラウザが表示しようとするので、それをキャンセルすることが必要です。

jQuery使っているのでそれで書いてしまいますが、使わない場合も基本は同じです。

3.1 ドロップエリア以外のドロップ禁止

単純にHTMLに対してのドラッグオーバー、ドロップイベント処理を書けばOK。


$(function(){
 //HTML自体にドラッグ&ドロップしても何もしないようにする
 $('html').on('dragover', function(e){
  e.preventDefault();
  e.stopPropagation();
 });
 $('html).on('drop', function(e){
  e.preventDefault();
  e.stopPropagation();
 });
 
});

3.2 ドロップエリアに対してのドラッグ&ドロップ

div.dropareaに対して、ドラッグオーバー、ドロップ処理を書きます。ドラッグオーバー時は文字を変えてみましょう。ドロップ時にajax_upload()関数を呼んでいます。


$(function(){
//ファイルをエリア内にドラッグしてきた
 $('div.droparea').on('dragover',function(e){
  e.preventDefault();
  e.stopPropagation();
  let p = ($this).find('p');
  $(p).text("ここにドロップ");
 });
//エリアから離れた(初期状態に戻す)
 $('div.droparea').on('dragleabe',function(e){
  e.preventDefault();
  e.stopPropagation();
  let p = ($this).find('p');
  $(p).text("ここにファイルをドラッグ&ドロップするか、クリックしてファイルを選択");
 });
//ドロップ
 $('div.droparea').on('drop',function(e){
  e.preventDefault();
  e.stopPropagation();

  let p = ($this).find('p');
  $(p).text("アップロード中");
  
  //fileを取得
  let file = e.originalEvent.dataTransfer.files[0];

  //ajaxファイルアップロード関数を呼ぶ(4で説明)
  ajax_upload(file);
 });

});

4. javascript (ajax ファイルアップロード部分)

ドロップされたので、ファイルをアップロードします。先ほどのdropイベント内でajax_upload(file)を呼んでいるので、その実装をします。

function ajax_upload(file)
{
 let fd = new FormData();
 fd.append("file", file);

 let options = {
  type:'POST',
  url: 'https://fileupload.abc/upload',
  data: fd,
  cache: false,
  contentType: false,
  processData: false,
  dataType: 'json'
 };

 $.ajax(
  options
 ).done(function(d){
  //json返ってきたので処理
 }).fail(function(d){

 }).always(function(){
  //完了
 });
}

フォームデータにappendしていけばパラメータ増やせるので、アップロードするファイルとデータを紐づけるなら、fd.append(‘target_id’, 15); とかやり、サーバ側でデータベースにid=15にこのファイルがアップロードされた的なtableを用意してinsertすればOKですね。

5. inputは、ドロップエリアのクリックイベントでinputを呼ぶ

inputはcssでdisplay:noneなため非表示です。クリックしようにも出来ないので、ドロップエリアのクリックイベントで、inputクリックを呼びます。


$(function(){

 //ドロップエリアがクリックされたので、inputをクリックしたことにする
 //ファイル選択ダイアログが出る
 $('div.droparea').on('click', function(e){
  e.preventDefault();
  e.stopPropagation();
  let elminput = $(this).parent().find('input');
  $(elminput).click();
 });

 //input type="file"でファイル選択された
 $('input[name="file"]').on('change', function(e){
 //ファイルを取得
  let file = $(this)[0].files[0];

  //ajaxファイルアップロード関数を呼ぶ(4で説明)
  ajax_upload(file);  
 });
});

6. サーバ側(php)

普段使っているフレームワークや、ファイルアップロード php とかで検索すればサンプル出てくると思います。
7の参考リンクのコードそのまま

&lt;?php

//アップロードされたファイル名を取得
$filename = $_FILES['file']['name'];

//ファイルサイズ取得
$filesize = $_FILES['file']['size'];

//アップロード場所
$location = "upload/".$filename;

//jsonで返す配列
$return_arr = array();

//uploadディレクトリにファイルをアップロード
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){

    //ここの処理不思議。(元サイトのまま)
    $src = "default.png";
    if(is_array(getimagesize($location))){
        $src = $location;
    }
    $return_arr = array("name" =&gt; $filename,"size" =&gt; $filesize, "src"=&gt; $src);
}

//最後はjsonで返す(ajaxでjson指定しているので)
echo json_encode($return_arr);

7.参考リンク

Drag and drop file upload with jQuery and AJAX
Learn how to implement drag and drop file upload with jQuery, AJAX, and PHP for a seamless and intuitive user experience.

コメント

  1. 通りすがり より:

    これ今日一日ずっと探して、非常に助かりました。

    細かい点ですが、
    $(this)が($this)になってる箇所があります。そこを直したら完全に動きました。

    有用な記事をありがとうございました。

  2. cfautog管理者 より:

    あ、確かに・・・($this)になっていますね・・・
    見ていただきありがとうございます!

タイトルとURLをコピーしました