Contact Us

Multiple File Upload with Dropzone.js and Laravel MediaLibrary Package – Laravel Daily

Mobile App | April 23, 2021

File upload is one of the most popular features in modern web. And we have quite a few libraries that can help us to build upload form. Let’s take two of my favorites – Dropzone on the front-end, and Spatie MediaLibrary on the back-end, and build a great uploading experience, in this tutorial.

First, what we’re building here. A simple for to add Projects, where you can also upload multiple files for every project.

As you can see, file upload has a big block instead of just an input file field. That’s how Dropzone works. But let’s take it one step at a time.

Step 1. MediaLibrary Installation

Let’s prepare the back-end, where we will actually store the files. We install the package like this:

Next, we publish their migration files, and run migrations:

By this time, we should have media table in our database.

This table uses Polymorphic Relations, so in our case will store records with model_type field equals appProject, which means that media file will be assigned to a project (not to a user, or anything else).

Step 2. Adding Dropzone.js code

In our Blade file, with the form, we need to add JavaScript code for Dropzone. There are multiple ways to do it, depending how you structure your whole Blade architecture, but here’s my version of resources/views/admin/projects/create.blade.php:

Ok, so what you can see here?

Ok ok, let’s add the JavaScript to make it actually work. At the end of the Blade file, I have this section:

Looks complicated, doesn’t it? No worries, I will point to the actual places you need to look at:

Notice: this JavaScript code will also work without any changes for edit form, not only create.

Now, keep in mind that this section cannot come just like that. In the main “parent” Blade layout file you should load some more scripts and @yield(‘scripts’) command. Here are excerpts from my resources/views/layouts/admin.blade.php:

So, as you can see, we’re loading jQuery, Bootstrap theme and Dropzone CSS+JS from CDN.

Ok, at this point, we should be able to drop the files into our Dropzone block, but they are not being uploaded yet. We need to implement that route(‘projects.storeMedia’) part.

Step 3. Uploading the Files

First, our routes/web.php will have this line:

Now, let’s go to app/Http/Controllers/ProjectsController.php:

Nothing magical here, just using standard Laravel/PHP functions to upload file, forming its unique filename, and returning it along with original name, as JSON result, so that Dropzone script could continue its work.

Notice: I store files temporarily in storage/tmp/uploads, you may choose other location.

Ok, we’re getting close. Now we have files in our server, but no entry in the database, because Project form isn’t submitted yet. It looks something like this:

Now, let’s hit Submit and see how to tie it all together.

Step 4. Submitting the Form

After we click Submit, we land on the method ProjectsController@store(), which is typical for Laravel resource controller. Here’s the code:

Looks simple, doesn’t it? Typical creating of Project record, and then going through each hidden document field (remember, we create them after each file upload), and adding them into Media Library.

At this point, you should have records in media database table, related to the Project’s ID that you have just saved.

Step 5. Edit/Update Form

If you want to have the same functionality in Edit form, the front-end part (Blade/JavaScript) remains almost unchanged, the important part is how to save the update files with record. So we’re looking at ProjectController again:

In other words, first we delete unused files, and then assign only those that are not in the media list yet.

Step Homework: Clean-up

I didn’t put it in this article, but you may want to handle the situation when people upload the files on the form but then don’t hit final Submit. It means that the files are still stored on the server.

It’s up to you how to deal with them – save in user’s “memory” somewhere for future use, or maybe create a separate cron-based Artisan command to cleanup all those files that have not been used.

That’s it! For more information, visit official documentations of both packages and Laravel Filesystem.

Like our articles?
Check out our Laravel online courses!

This content was originally published here.