Laravel 10 Dropzone Multiple Image Upload

Dropzone is an open-source JavaScript library that provides a drag-and-drop file upload feature for websites. It allows users to upload files by simply dragging and dropping them onto a designated area on the web page, instead of having to browse for the files manually.

In this guide, we are going to create a simple project to upload images with DropzoneJS. Here’s the preview of our project:

Last tested on: Laravel 10.6.2

Table of Contents

  1. Install Laravel and Basic Configurations
  2. Create Model, Migration & Controller
  3. Register Routes
  4. Create Blade File

Install Laravel and Basic Configurations

Each Laravel project needs this thing. That’s why I have written an article on this topic. Please see this part from here: Install Laravel and Basic Configurations

Create Model, Migration & Controller

In this step, we are going to create the book model, migration and controller. Let’s create these at once:

php artisan make:model ImageUpload -mcr

After creating the files, open the migration file from database/migrations and update the up() function like this:

timestamp_create_image_uploads_table.php
public function up()
{
    Schema::create('image_uploads', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('filename');
        $table->timestamps();
    });
}

We’ve to migrate the migration:

php artisan migrate

After that open Book model and add a $fillable array:

app/Models/ImageUpload.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class ImageUpload extends Model
{
    protected $fillable = [
        'filename'
    ];
}

Lastly, open ImageUploadController from app\Http\Controllers and paste this code:

<?php

namespace App\Http\Controllers;

use App\Models\ImageUpload;
use Illuminate\Http\Request;

class ImageUploadController extends Controller
{
    public function upload()
    {
        $images = ImageUpload::query()->orderBy('id', 'desc')->get();

        return view('image_upload', compact('images'));
    }

    public function store(Request $request)
    {
        $image = $request->file('file');
        $imageName = $image->getClientOriginalName();
        $image->move(storage_path('app/public'), $imageName);

        $imageUpload = new ImageUpload();
        $imageUpload->filename = $imageName;
        $imageUpload->save();
        return response()->json(['success' => $imageName]);
    }

    public function delete(Request $request)
    {
        $filename = $request->get('filename');
        ImageUpload::where('filename', $filename)->delete();
        $path = public_path() . '/images/' . $filename;
        if (file_exists($path)) {
            unlink($path);
        }
        return $filename;
    }
}

Register Routes

Let’s create the routes:

routes/web.php
use App\Http\Controllers\ImageUploadController;
use Illuminate\Support\Facades\Route;

Route::get('upload', [ImageUploadController::class, 'upload']);
Route::post('upload/store', [ImageUploadController::class, 'store']);
Route::post('delete', [ImageUploadController::class, 'delete']);

Create Blade File

Go to resources/views folder and make a blade file named image_upload.blade.php for image upload.

image_upload.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Laravel 10 Dropzone Multiple Image Upload</title>
    <meta name="_token" content="{{csrf_token()}}"/>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.css">
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/dropzone.min.js"></script>
</head>
<body>
<div class="container">

    <div class="text-center" style="margin: 20px 0px 20px 0px;">
        <a href="https://shouts.dev/" target="_blank"><img src="https://shouts.dev/img/logo.webp"></a><br>
        <span class="text-secondary">Laravel 10 Dropzone Multiple Image Upload</span>
    </div>

    <form method="post" action="{{url('upload/store')}}" enctype="multipart/form-data"
          class="dropzone" id="dropzone">
        @csrf
    </form>

    @if($images->count() > 0)
        <h4 class="mt-4 mb-4">Uploaded Files</h4>
        <div class="container text-center">
            <div class="row">
                @foreach($images as $image)
                    <div class="col col-md-4">
                        <div class="card" style="width: 18rem;">
                            <img class="img-fluid p-1" alt="img" src="{{ Storage::url($image->filename) }}">
                        </div>
                    </div>
                @endforeach
            </div>
        </div>

    @endif
</div>

<script type="text/javascript">
    Dropzone.options.dropzone =
        {
            maxFilesize: 12,
            renameFile: function (file) {
                var dt = new Date();
                var time = dt.getTime();
                return time + file.name;
            },
            acceptedFiles: ".jpeg,.jpg,.png,.gif",
            addRemoveLinks: true,
            timeout: 50000,
            removedfile: function (file) {
                var name = file.upload.filename;
                $.ajax({
                    headers: {
                        'X-CSRF-TOKEN': '{{ csrf_token() }}'
                    },
                    type: 'POST',
                    url: '{{ url("delete") }}',
                    data: {filename: name},
                    success: function (data) {
                        console.log("File has been successfully removed!!");
                    },
                    error: function (e) {
                        console.log(e);
                    }
                });
                var fileRef;
                return (fileRef = file.previewElement) != null ?
                    fileRef.parentNode.removeChild(file.previewElement) : void 0;
            },

            success: function (file, response) {
                console.log(response);
            },
            error: function (file, response) {
                return false;
            }
        };
</script>

</body>
</html>

Our application is ready to run. Let’s run our project:

php artisan serve

Now go to the URL and test the uploader:

http://localhost:8000/upload

That's all. Thanks for reading. 👍