東京都府中市、九段下のWEB制作会社Maromaroのブログです

2022.06.13

taka

jQueryで画面遷移無しのファイルをドラッグ&ドロップ出来るフォームを作る

こんにちは
Takaです。

今回はjQueryで画面遷移無しのファイルをドラッグ&ドロップ出来るアップローダーを作る方法をご紹介します。

フロントのみで裏側の仕組み(PHPなど)は割愛させて頂きます。

実装方法など

まずは基本的なHTMLは以下で考えます。

<form action="/maromaro/uploader/upload" method="POST" enctype="multipart/form-data">
  <div id="Uploader">
    <input id="file_input" type="file" name="files">
  </div>
</form>

基本的なHTMLはこの記述だけで十分です。
inputの場所も自由な場所にしてもらって大丈夫です。
ファイル選択を行わせない場合は非表示でも問題ありません。

jQueryは以下のような記述になります。

$(function(){
    // ドラッグしたままエリアに乗ったとき
    $(document).on('dragover', 'body, #file_drag_drop_area_stl', function (event) {
        event.preventDefault();
        //以下にファイルをドラッグオンした場合の動作を記述できます。
    });
    // ドラッグしたままエリアに外れたとき
    $(document).on('dragleave', 'body, #file_drag_drop_area_stl', function (event) {
        event.preventDefault();
        //以下にファイルをドラッグオフした場合の動作を記述できます。
    });


    // ドラッグ&ドロップした時
    $(document).on('drop', 'body', function (event) {
      let org_e = event;
      if (event.originalEvent) {
          org_e = event.originalEvent;
      }
      org_e.preventDefault();
      //ファイルのセット
      file_input.files = org_e.dataTransfer.files;
      //アップロードするファイルのデータ取得
      var fileData = document.getElementById("file_input").files[0];
      //フォームデータを作成する
      var form = new FormData();
      //フォームデータにアップロードファイルの情報追加
      form.append("file", fileData);
      //以下よりajax
      //フォームデータに格納されたものがPOSTされるので、後は適宜裏側で処理
      $.ajax({
          type: "POST",
          url: "/hogehoge/upload",
          data: form,
          processData: false,
          contentType: false,
          success: function (response) {
            //成功時の処理 response に戻り値が格納される
          },
          error: function (response) {
            //エラー時の処理 response に戻り値が格納される
          }
      });
    });
  });

詳細はコメント中に記載致しました。
コピーペーストで少し修正すれば動作すると思います。

画面遷移無しのため、Ajaxを使用しております。
画面遷移有りの場合はAjaxを使用せずに、
Ajax部分を

$(‘form’).submit();

のようにして頂ければ問題ないかと思います。
Laravel等の場合はCSRFの設定をしないとエラーになると思うので、気を付けてください。

ちなみにリアルタイムでプログレスバー(アップロードの進捗等)を表示したい場合は以下のようにAjax部分にXHRを追記してください。

$.ajax({
          type: "POST",
          url: "/hogehoge/upload",
          data: form,
          processData: false,
          contentType: false,
//以下に追加           xhr : function(){             var XHR = $.ajaxSettings.xhr();             if(XHR.upload){                 XHR.upload.addEventListener('progress',function(e){                   //アップロード時の進捗状況を取得                     var progre = parseInt(e.loaded/e.total*100);                 }, false);             }             return XHR;           },           success: function (response) {             //成功時の処理 response に戻り値が格納される           },           error: function (response) {             //エラー時の処理 response に戻り値が格納される           } });

progre部分に約0.5秒に1回(正確な時間は仕様書みても見つけられず… そのため時間については曖昧です)、
進捗状況(0 ~ 100の整数)が格納されます。
※最大値が100にになるよう直してます

取得した数値はテキストとして使用するかCSS(width等)に使用するなど、良い感じに使用してください。

以上Takaでした。