In this short blog post I will share with you how I made queued multiple file upload possible with Laravel and a nice jQuery plugin called Dropzone.js.
I needed to give the user the ability to upload multiple images at once and instantly see visual feedback on the upload progress and/or errors that come up during the upload.
Dropzone.js comes with nice CSS and Javascript that make it a breeze to work with HTML 5 file upload API. It provides you with a file input container that users can drag and drop files unto or just click the container to select multiple files from the file system.
From the plugin docs: Dropzone.js works in :
- Chrome 7+
- Firefox 4+
- IE 10+
- Opera 12+ (Currently disabled for MacOS because their API is buggy)
- Safari 5+
For all the other browsers, dropzone provides an oldschool file input fallback.
To implement this awesome plugin here is what you need to do :
1) Download Dropzone.js Javascript and CSS and reference to them from your view (or layout):
{{ HTML::style('css/basic.css');}}
{{ HTML::script('js/vendor/dropzone.js') }}
2) In your view have a form element with class dropzone, action being the path to your upload route or controller and some id:
Upload using Dropzone.js
<form action="{{ url('user/upload')}}" class="dropzone" id="my-awesome-dropzone"></form>
At this point if you go to the view where you implemented the dropzone plugin you should see it working. But it should give you errors when you try to upload files because the action where it tries to upload doesn’t exist yet. Now we need to hook up the form to a route or controller.
I have a controller called “user”, and the action that I need to build should do the following things:
- Validate my file upload to be an image (if I want only images) and below certain size limit in kilobytes.
- If the validation passes, upload the file and rename it to a random string to avoid collisions.
- If validation does not pass return the first error to the user and return status code 400.
- Upon file upload success make a JSON response with code 200 (because 200 is commonly used as a success response)
- Otherwise throw an error letting the user know that there was a server error.
Now that I have my algorithm figured out, I build the controller action :
public function post_upload(){
$input = Input::all();
$rules = array(
'file' => 'image|max:3000',
);
$validation = Validator::make($input, $rules);
if ($validation->fails())
{
return Response::make($validation->errors->first(), 400);
}
$file = Input::file('file');
$extension = File::extension($file['name']);
$directory = path('public').'uploads/'.sha1(time());
$filename = sha1(time().time()).".{$extension}";
$upload_success = Input::upload('file', $directory, $filename);
if( $upload_success ) {
return Response::json('success', 200);
} else {
return Response::json('error', 400);
}
}
Side note, make sure you create a folder called “uploads” in the public folder because other files and folders will be created there.
Now if you have your routes set up as mine (a user controller must be registered in the routes) and this action implemented you should see that the files are uploaded successfully and if you navigate to your public/uploads folder you should see something like this:
That’s it!
If you need the files to be resized/cropped before saving, make sure you check out some bundles on bundles.laravel.com, specifically :
http://bundles.laravel.com/bundle/resizer
Let me know if you have any questions/problems with this.






Thanks for all the Laravel Tutorials. Keep them coming!
Hi,
Thanks for this tutorial but your form’s HTML is not displayed correctly. It should be like below;
And if you enabled CSRF protection, which you must, then you have to insert token in your form;
{{ Form::token() }}
WordPress messed my previous comment. The HTML form should be;
form id=”my-awesome-dropzone” action=”{{ url(‘user/upload’) }}” class=”dropzone”
Can you please share a tutorial where we can show the save image with the post, Like you made the blog tutorial if some one want to publish the image with post how we can do that ? I am waiting for your positive response.
Thanks
Regards,
on ln 18 you have $directory = path(‘public’).’uploads/’.sha1(time());
Does anyone know in Laravel4, how to access path()? It does not appear to be present.
just try to do ‘public/uploads’ instead of using “path(public).’uploads’”.
If I dont want to create new folder just saving all files in one folder how I can do that?
Just replace
path(‘public’).’uploads/’.sha1(time());
with
path(‘public’).’uploads/yourfolder’);
=)
Hi, thank you for your tutorial, works perfectly.
Sometimes i need to upload only one file and prevent multiple choice. I can’t find how i can do that with dropzone.
Is it possible?
Thank you one file
I have searched its documentation and I don’t think you can do that with dropzone.
As a better alternative for AJAX style uploads I recommend this – http://malsup.com/jquery/form/#file-upload
Hi thanks for this turorial. One thing, iv got problems when image width dimension is above 2031 px. I wont upload and give no error message on the dropzone. The green check mark is shown but wont upload. Thanks, Hope you can help me on this.
That probably is the PHP upload limit issue. Try increasing the max size of file uploads
Hi I’m new to Laravel and your code helped me a lot. My problem after uploading files is to show or view the list of files uploaded. I hope you can help me.
Are you using Laravel 3 or 4 ?
I prefer to save information about the uploaded files into the database and then just showing the items from the database
How to add Remove per file and remove all files option …
Thanks in Advance
You would have to make that as a separate AJAX call to the server. Let’s say your user is logged in, then from the page with file uploads you make a POST request to your application’s API or controller action with the ID of the file, and on the server side you have to make sure that this file indeed belongs to the user and then you can use Laravel’s file removal function to remove the file.
Does that solve your question?