Laravel 8 Dropzone.js Example: Drag and Drop Image/File Upload Tutorial with Progress Bar and Image Preview

Last updated on by Digamber

This comprehensive Laravel 8|7 file uploading tutorial helps you create drag and drop files or image uploading using the Dropzone js plugin. Apparently, we will shed light on single and multiple file uploading functionalities. Also, we will display the file uploading progress with progress bars.

DropzoneJS is a popular and profound open-source library that allows you to drag ’n’ drop file uploads with image previews. Undoubtedly, it is lightweight, and most importantly, it doesn’t require an external library (such as jQuery). Unbound customization is its core characteristic; you can build image previews, upload progress bars, multiple files, and synchronous uploads with it pretty easily.

Create New Laravel Project

Run following command to install Laravel application, however if already installed then skip installation.

composer create-project laravel/laravel --prefer-dist laravel-drag-drop-file-upload-example

Get into the application root:

cd laravel-drag-drop-file-upload-example

Create Route

Next, define the two routes simultaneously. One route is responsible for displaying the view. The other one conjugates the logic for uploading the single & multiple files/images and displaying image preview with progress bar for every individual uploaded file.

Include the following code in routes/web.php file.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\FileUploadController;


/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('upload-ui', [FileUploadController::class, 'dropzoneUi' ]);
Route::post('file-upload', [FileUploadController::class, 'dropzoneFileUpload' ])->name('dropzoneFileUpload');

Setting Up File Upload Controller

To build the drag and drop file uploading feature we need to create a controller, so shoot the below command from command prompt.

php artisan make:controller FileUploadController

Incorporate the given below code in app/Http/Controllers/FileUploadController.php file.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FileUploadController extends Controller
{
    /** 
     * Generate Upload View 
     * 
     * @return void 

    */  

    public  function dropzoneUi()  
    {  
        return view('upload-view');  
    }  

    /** 
     * File Upload Method 
     * 
     * @return void 
     */  

    public  function dropzoneFileUpload(Request $request)  
    {  
        $image = $request->file('file');

        $imageName = time().'.'.$image->extension(); 
        $image->move(public_path('images'),$imageName);  

        return response()->json(['success'=>$imageName]);
    }
}

Create Blade View

Ultimately, we need to create a resources/views/dropzone-file-upload.blade.php file; this will evoke the drag and drop file view on the frontend.

Add the following code in resources/views/dropzone-file-upload.blade.php file.

<!DOCTYPE html>
<html>

<head>
    <title>Laravel 8|7 Drag And Drop File/Image Upload Examle </title>

    <link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/dropzone.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.2/min/dropzone.min.js"></script>

    <script>
        var dropzone = new Dropzone('#file-upload', {
            previewTemplate: document.querySelector('#preview-template').innerHTML,
            parallelUploads: 3,
            thumbnailHeight: 150,
            thumbnailWidth: 150,
            maxFilesize: 5,
            filesizeBase: 1500,
            thumbnail: function (file, dataUrl) {
                if (file.previewElement) {
                    file.previewElement.classList.remove("dz-file-preview");
                    var images = file.previewElement.querySelectorAll("[data-dz-thumbnail]");
                    for (var i = 0; i < images.length; i++) {
                        var thumbnailElement = images[i];
                        thumbnailElement.alt = file.name;
                        thumbnailElement.src = dataUrl;
                    }
                    setTimeout(function () {
                        file.previewElement.classList.add("dz-image-preview");
                    }, 1);
                }
            }
        });
        
        var minSteps = 6,
            maxSteps = 60,
            timeBetweenSteps = 100,
            bytesPerStep = 100000;

        dropzone.uploadFiles = function (files) {
            var self = this;

            for (var i = 0; i < files.length; i++) {

                var file = files[i];
                totalSteps = Math.round(Math.min(maxSteps, Math.max(minSteps, file.size / bytesPerStep)));

                for (var step = 0; step < totalSteps; step++) {
                    var duration = timeBetweenSteps * (step + 1);
                    setTimeout(function (file, totalSteps, step) {
                        return function () {
                            file.upload = {
                                progress: 100 * (step + 1) / totalSteps,
                                total: file.size,
                                bytesSent: (step + 1) * file.size / totalSteps
                            };

                            self.emit('uploadprogress', file, file.upload.progress, file.upload
                                .bytesSent);
                            if (file.upload.progress == 100) {
                                file.status = Dropzone.SUCCESS;
                                self.emit("success", file, 'success', null);
                                self.emit("complete", file);
                                self.processQueue();
                            }
                        };
                    }(file, totalSteps, step), duration);
                }
            }
        }

    </script>

    <style>
        .dropzone {
            background: #e3e6ff;
            border-radius: 13px;
            max-width: 550px;
            margin-left: auto;
            margin-right: auto;
            border: 2px dotted #1833FF;
            margin-top: 50px;
        }

    </style>
</head>

<body>
    <div id="dropzone">
        <form action="{{ route('dropzoneFileUpload') }}" class="dropzone" id="file-upload" enctype="multipart/form-data">
            @csrf
            <div class="dz-message">
                Drag and Drop Single/Multiple Files Here<br>
            </div>
        </form>
    </div>
</body>

</html>

The Dropzone plugin is invoked here using CDN links (JavaScript and CSS).

The dropzone object is initialized with file-upload id; we have also applied minor settings for file uploading functionality.

To style the drag and drop component, we incorporated styling using CSS. We passed the dropzoneFileUpload with the route() method within the action directive.

Now, you can upload single and multiple files using drag and drop, also with click event.

Start Laravel 8 Dropzone Application

Execute the command to start the application:

php artisan serve
http://localhost:8000/upload-ui

This is going to be the result when you successfully upload the images using drag and drop.

Drag and Drop Image/File Upload Tutorial with Progress Bar and Image Preview

Summary

We have completed the file uploading tutorial and created drag and drop file upload in laravel using the Dropzone.js plugin. You can read more about the Dropzone package here.