You are here
Home > Posts tagged "javascript"

ファイルのアップロード(5)複数の画像ファイルをアップロード

Dropzone.jsを使用する利点は、ファイルアップロードの途中経過を表示するようになりUIが良くなるだけでありません。1画面で複数の画像ファイルを一度にアップすることができます。

もちろん、以下のように複数のファイルのアップロードは、Dropzone.jsを使用しなくても可能です。

<form
    method="POST"
    action="/demo/public/user/upload"
    class="form-horizontal"
    role="form"
    enctype="multipart/form-data">
    {{ csrf_field() }}
...
    <input type="file" name="file1">
    <input type="file" name="file2">
...
</form>

しかし、以下のポストで説明したように、

ファイルのサイズの制限・制限なしでも制限ある

ウェブサーバーによる制限により、1フォームでアップロードできるファイルの数は、すべてのファイルを足したファイルのサイズになります。

例えば、

post_max_size = 2M
upload_max_filesize = 1M

の設定なら、1フォームでは、最大1Mのファイルが2つまでしかアップロード可能でありません。

しかし、Dropzone.jsを使用すれば、ajaxを使用するので、それぞれのファイルアップロードは、1フォームで1つのファイルのアップロードとなり、この例では、1Mファイルをいくつでもアップロード可能となります。

そして、この複数のファイルのアップロードに対応するプログラムの変更といえば、

まず、フロントエンド、

Dropzone.jsでアップロード途中経過を表示

とまったく同じです。変更はありません。

アップロード時、複数のファイルを選択してドラッグするか、ファイルダイアログで複数のファイルを選択して実行すれば以下のようにアップされます。
multiple

バックエンドは、

namespace App\Http\Controllers\User;
 
use Illuminate\Http\Request;
 
use App\Http\Requests;
use App\Http\Controllers\Controller;
 
use Validator;
 
class UserController extends Controller
{
...
    public function getUpload()
    {
        return view('user/upload');
    }
 
    public function postUpload(Request $request)
    {
        $file = $request->file('file');
        $filename = $file->getClientOriginalName();
        $file->move(public_path('images'), $filename)
    }
}

と、アップしたファイル名で、/public/imagesのディレクトリに保存するように変更します。

同時にアップするファイル数を制限したいなら、

<script type="text/javascript">
       
Dropzone.options.imageUpload = {
    dictDefaultMessage: 'アップロードするファイルをここへドロップしてください',
    acceptedFiles: '.jpg, .jpeg',
    maxFilesize: 5 // 5MBまで
  maxFiles: 2 // ファイルは2つまでアップロード可能
}
</script>

と、Dropzone.jsの設定で、maxFilesを指定します。

only2

このように3番目のファイルは、アップロード不可となります。

ファイルのアップロード(3)Dropzone.jsでアップロード途中経過を表示

今まで話したファイルアップロードは、基本でもっとも簡単にプログラムできるものです。

しかし、アップロードするファイルのサイズが大きく、アップロードに時間がかかるようになると、送信ボタンを押してからじ~っと何も起きない画面を見ているのは、退屈でもありちょっと心配ですね。これ、ちゃんと動いているのかなと。

要は、「アップロード中です」とか「80%アップロード完了」したとか、しかもそれをビジュアルで伝えてくれれば最高です。それを行ってくれるのが今回紹介するツール、Dropzone.jsです。

upload1

「アップロードするファイルをここへドラッグしてください」にファイルをドラッグすると、

upload2

このように、アップロードの画像ファイルのサムナイルの中にアップロードの途中経過をバーで表示してくれます。

ファイル完了時は、

upload3

必要な設定は、

https://github.com/enyo/dropzone/archive/master.zip

よりダウンロードして解凍してから、assets/jsのディレクトリに入れて、画面のテンプレートを以下のように編集します。

<div class="form-group{{ $errors->has('file') ? ' has-error' : '' }}">
    <div>
        <form
             method="POST"
             action="/demo/public/user/upload"
             class="dropzone"
             id="imageUpload"
             enctype="multipart/form-data">
             {{ csrf_field() }}
         </form>
    </div>
</div>

気づきましたか、
<input type="file" name="file">

<input type="submit">
がないことに。

ちなみにデフォルトのファイル変数名はfileですが、設定変更できます。

そして、レイアウトのテンプレートを以下のように編集します。

...
<head>
...
<link href="{{ url('assets/css/dropzone/dropzone.min.css') }}" rel="stylesheet" type="text/css">
...
</head>
<body>
...
 
<script src="{{ url('assets/js/dropzone/dropzone.min.js') }}"></script>
 
<script type="text/javascript">
      
Dropzone.options.imageUpload = {
    dictDefaultMessage: 'アップロードするファイルをここへドロップしてください',
    acceptedFiles: '.jpg, .jpeg',
    maxFilesize: 5 // 5MBまで
}
</script>
...

上の設定では、ファイルをドロップする場所のメッセージ、アップロードを許すMIMEあるいは拡張子(jpegのみ)、最大のファイルのサイズ(5MBまで)としています。他にもいろいろな設定があります。以下を参照にしてください。

http://www.dropzonejs.com/#configuration

将来は、これらの設定を使用した複雑な例を紹介する予定です。

Select2 セレクト複数選択

今回は人気のドロップダウンスクリプト、Select2を紹介します。

通常のドロップダウンリストは、

<div class="form-group{{ $errors->has('category') ? ' has-error' : '' }}">
    <label class="col-md-4 control-label">分類</label>

    <div class="col-md-6">
        {!! Form::select('category', ['犬', '猫', '猿'], null, ['class' => 'form-control']) !!}
    </div>
</div>

とテンプレートで指定すると、

select1

と表示。

これに、

<div class="form-group{{ $errors->has('category') ? ' has-error' : '' }}">
    <label class="col-md-4 control-label">分類</label>

    <div class="col-md-6">
        {!! Form::select('category[]', ['犬', '猫', '猿'], null, ['class' => 'form-control', 'multiple' => 'multiple']) !!}
    </div>
</div>

'multiple' => 'multiple'を追加すると、

multiple1

と複数選択に変わります。

しかし、この複数選択にSelect2を使用すれば、

multiple2

のように、ドロップダウンから複数選択して、最初の行に選択した値を表示してくれます。また、そこでXをクリックすることで削除もできます。

必要な設定は、

まず、

https://github.com/select2/select2/archive/master.zip

よりダウンロードして解凍してから、レイアウトのテンプレートを以下のように編集します。

...
<head>
...
<link href="{{ url('assets/css/select2/select2.min.css') }}" rel="stylesheet" type="text/css">
...
</head>
<body>
...

<script src="{{ url('assets/js/select2/select2.min.js') }}"></script>
<script src="{{ url('assets/js/select2/ja.js') }}"></script>

<script type="text/javascript">
      $(document).ready(function() {
          $(".js-multiple").select2({ width: 'resolve' });
      });
</script>
...

そして、画面のテンプレートを、

<div class="form-group{{ $errors->has('category') ? ' has-error' : '' }}">
    <label class="col-md-4 control-label">分類</label>

    <div class="col-md-6">
        {!! Form::select('category[]', ['犬', '猫', '猿'], null, ['class' => 'form-control js-multiple', 'multiple' => 'multiple']) !!}
    </div>
</div>

と編集します。

Select2には他にもいろいろな機能があります。

https://select2.github.io/examples.html

Top