Article

Multiple Image Uploader with Laravel 5.5 and Dropzone.js

Jan 19, 2020 3,183
Multiple Image Uploader with Laravel 5.5 and Dropzone.js

In a lot of our projects we need to make a multiple image uploader. In this tutorial, We will make an advanced AJAX uploader. This uploader will:

  1. upload multiple images via AJAX.
  2. show the thumbnails of those uploads using Dropzone.js
  3. show the URL link of the uploaded images and copy it to the clipboard using clipboardjs.

Let’s start !

The Controller:

First of all, let’s make a controller for our upload function:

php artisan make:controller UploadController

let’s write our upload function (each line explained)

public function upload(Request $request)
{
    // Creating a new time instance, we'll use it to name our file and declare the path
    $time = Carbon::now();
    // Requesting the file from the form
    $image = $request->file('file');
    // Getting the extension of the file 
    $extension = $image->getClientOriginalExtension();
    // Creating the directory, for example, if the date = 18/10/2017, the directory will be 2017/10/
    $directory = date_format($time, 'Y') . '/' . date_format($time, 'm');
    // Creating the file name: random string followed by the day, random number and the hour
    $filename = str_random(5).date_format($time,'d').rand(1,9).date_format($time,'h').".".$extension;
    // This is our upload main function, storing the image in the storage that named 'public'
    $upload_success = $image->storeAs($directory, $filename, 'public');
    // If the upload is successful, return the name of directory/filename of the upload.
    if ($upload_success) {
        return response()->json($upload_success, 200);
    }
    // Else, return error 400
    else {
        return response()->json('error', 400);
    }
}

As we can see, we store the file using storeAs , in the storage that named public . that can be customized from config/filesystems you’ll see a public system there, I changed it to look like this:

'public' => [
    'driver' => 'local',
    'root' => public_path('uploads'),
    'url' => env('APP_URL').'/uploads',
    'visibility' => 'public',
]

This way, the files will be uploaded to public/uploads/ .

The Route:

In our routes/web file will add this post route which will go to our controller:

Route::post('/upload' , 'UploadController@upload');

The View:

let’s make a blade file that contains our uploader and its javascript functions:

in head section in our blade file, we’ll add Dropzone.js dependencies:

<script src="{{url('js/dropzone.js')}}"></script>
<link rel="stylesheet" href="{{url('css/dropzone.css')}}">

Next, we’ll create the uploading form:

<form action="{{ url('/admin/upload') }}" enctype="multipart/form-data" class="dropzone" id="my-dropzone">
    {{ csrf_field() }}
</form>

Notice that we added csrf_field() . The form will not work properly without it!

now, let’s start adding the footer scripts:

First, let’s add clipboardjs script, which we’ll be using to copy the URL of the uploaded images

The first script will be the upload script:

<script>
Dropzone.options.myDropzone = {
        paramName: 'file',
        maxFilesize: 5, // MB
        maxFiles: 20,
        acceptedFiles: ".jpeg,.jpg,.png,.gif",
        init: function() {
            this.on("success", function(file, response) {
                var a = document.createElement('span');
                a.className = "thumb-url btn btn-primary";
                a.setAttribute('data-clipboard-text','{{url('/uploads')}}'+'/'+response);
                a.innerHTML = "copy url";
                file.previewTemplate.appendChild(a);
            });
        }
    };
</script>

If you want to stop right here, and you don’t need to copy the URLs, you can delete the init function from the above script init:function(){...} and you’ll be done! In the above script, specifically on success function, we can see that we made a variable a which is a span that will be embedded after each uploaded thumbnail.

This span has a class thumb-url and a new attribute that called data-clipboard-text which contains the response from our upload function. Our span also has the classes btn btn-primary , those are boostrap classes, we will be using bootstrap to show the tooltip when the user click to copy the URL.

Let’s add the clipboard js:

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

Now let’s write our function:

<script>
    $('.thumb-url').tooltip({
        trigger: 'click',
        placement: 'bottom'
    });

    function setTooltip(btn, message) {
        $(btn).tooltip('hide')
            .attr('data-original-title', message)
            .tooltip('show');
    }

    function hideTooltip(btn) {
        setTimeout(function() {
            $(btn).tooltip('hide');
        }, 500);
    }

    var clipboard = new Clipboard('.thumb-url');

    clipboard.on('success', function(e) {
        e.clearSelection();
        setTooltip(e.trigger, 'Copied!');
        hideTooltip(e.trigger);
    });

    clipboard.on('error', function(e) {
        e.clearSelection();
        setTooltip(e.trigger, 'Failed');
        hideTooltip(e.trigger);
    });
</script>

This way, when the user click on the copy button, it will show a tooltip that says copied! and the URL will be copied to the clipboard! I hope you find this tutorial helpful

Nice coding! 🌹

Ahmet Yusuf
Ahmet Yusuf

As a full-stack developer with a master’s degree in Electrical and Computer Engineering, I’m deeply passionate about web design and development. I enjoy exploring new technologies and sharing insights into creating user-centered digital experiences in this exciting field.

Related Articles

You may also like

See all posts
How to Survive as a Web Developer in 2025 cover

How to Survive as a Web Developer in 2025

Being a web developer in 2025 is challenging. The industry moves fast, AI is conquering front-end jo (...)

Read article
Useful Color Generators in SCSS cover

Useful Color Generators in SCSS

Writing color classes for your project could take a lot of your time. luckily, SCSS functions will m (...)

Read article
What is WEP Standard and What are the Limitations of Using it? cover

What is WEP Standard and What are the Limitations of Using it?

WEP, Wired Equivalent Privacy, is an older security protocol that is specified in 802.11b Wi-Fi IEEE (...)

Read article