Creating Multi-files Uploader with blueimp jQuery Plugin & PHP

Blueimp File Upload is a popular free jQuery File upload plugin which can handle multiple file uploads, it comes with many attractive features like drag & drop support, progress bars, client side preview of pictures, audios and videos. It works with any server-side platform such as Google App Engine, PHP, Python, Ruby on Rails, Java. Today I am going to use this wonderful jQuery plugin to create a custom file uploader interface (without Bootstrap or jQuery UI layout). With little bit of CSS and jQuery our final multiple file uploader should look as picture below, we can then drag and drop files on it, preview image or play audio or video files before even uploading them to the server.

Browser Support

  • 6+
  • v31+
  • v30+
  • v4+
  • v11+

Mark Up

In the HTML code, we have outer DIV element which holds everything together, inside we have drop zone, file input, button and files container elements. We will use CSS to style these elements, since most of these elements will be controlled by jQuery script, we do not need to add anything else, unless you have other ideas on your mind.
HTML
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
<div class="upload-wrapper"> <div id="error_output"></div> <!-- file drop zone --> <div id="dropzone"> <i>Drop files here</i> <!-- upload button --> <span class="button btn-blue input-file"> Browse Files <input id="fileupload" type="file" name="files[]" multiple> </span> </div> <!-- The container for the uploaded files --> <div id="files" class="files"></div> </div>

Include jQuery Scripts

Once we have our HTML elements in position, we need to include jQuery library along with blueimp jQuery scripts. Plugin requires jQuery UI to function, but fortunately blueimp comes with smaller, lightweight version of original jQuery UI.
JS
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
<!-- include jQuery --> <script src="js/jquery.min.js"></script> <!-- The jQuery UI widget factory, can be omitted if jQuery UI is already included --> <script src="js/vendor/jquery.ui.widget.js"></script> <!-- The Load Image plugin is included for the preview images and image resizing functionality --> <script src="js/load-image.all.min.js"></script> <!-- The Canvas to Blob plugin is included for image resizing functionality --> <script src="js/canvas-to-blob.min.js"></script> <!-- The Iframe Transport is required for browsers without support for XHR file uploads --> <script src="js/jquery.iframe-transport.js"></script> <!-- The XDomainRequest Transport is included for cross-domain file deletion for IE 8 and IE 9 --> <!--[if (gte IE 8)&(lt IE 10)]> <script src="js/cors/jquery.xdr-transport.js"></script> <![endif]--> <script src="js/jquery.fileupload.js"></script> <!-- The File Upload processing plugin --> <script src="js/jquery.fileupload-process.js"></script> <!-- The File Upload image preview & resize plugin --> <script src="js/jquery.fileupload-image.js"></script> <script src="js/jquery.fileupload-video.js"></script> <!-- optional for video uploads --> <script src="js/jquery.fileupload-audio.js"></script> <!-- optional for audio uploads --> <script src="js/jquery.fileupload-validate.js"></script>

Initialization

We now have included the required scripts for our file upload, it is time to initialize file upload plugin with various Options available, which can be changed according to one's needs.
JQUERY
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
var fi = $('#fileupload'); //file input //initialize blueimp fileupload plugin var process_url = 'http://path/to/file/upload.php'; //PHP script fi.fileupload({ url: process_url, dataType: 'json', autoUpload: false, acceptFileTypes: /(\.|\/)(gif|jpe?g|png|mp4|mp3)$/i, maxFileSize: 1048576, //1MB // Enable image resizing, except for Android and Opera, // which actually support image resizing, but fail to // send Blob objects via XHR requests: disableImageResize: /Android(?!.*Chrome)|Opera/ .test(window.navigator.userAgent), previewMaxWidth: 50, previewMaxHeight: 50, previewCrop: true, dropZone: $('#dropzone') //specify element for drop zone });
As you can see it is accepting number of file formats, and maximum file size allowed is 1 MB, these options only work if we have included "jquery.fileupload-validate.js" script, and features like image preview requires "jquery.fileupload-image.js", so basically even if you don't include some of these dependency scripts, file upload will work perfectly, but some of "those" functionality will be absent.

Adding Files to Queue

To add files in the file container queue for upload, we use add callback method. Since autoUpload is set false in initialization option above, files will not be uploaded automatically, we will be creating upload buttons instead, which will trigger file upload.
JQUERY
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
var progressBar = $('<div/>').addClass('progress').append($('<div/>').addClass('progress-bar')); //create progress bar var uploadButton = $('<button/>').addClass('button btn-blue upload').text('Upload'); //create upload button uploadButton.on('click', function () { //button click function var $this = $(this), data = $this.data(); data.submit().always(function () { //upload the file $this.remove(); //remove this button }); }); fi.on('fileuploadadd', function (e, data) { data.context = $('<div/>').addClass('file-wrapper').appendTo('#files'); //create new DIV with "file-wrapper" class $.each(data.files, function (index, file){ //loop though each file var node = $('<div/>').addClass('file-row'); //create a new node with "file-row" class var removeBtn = $('<button/>').addClass('button btn-red remove').text('Remove'); //create new remove button removeBtn.on('click', function(e, data){ //remove button function $(this).parent().parent().remove(); //remove file's wrapper to remove queued file }); //create file info text, name and file size var file_txt = $('<div/>').addClass('file-row-text').append('<span>'+file.name + ' (' +format_size(file.size) + ')' + '</span>'); file_txt.append(removeBtn); //add remove button inside info text element file_txt.prependTo(node).append(uploadButton.clone(true).data(data)); //add to node element progressBar.clone().appendTo(file_txt); //add progress bar if (!index){ node.prepend(file.preview); //add image preview } node.appendTo(data.context); //attach node to data context }); });

Upload Progress

Remember the progress bar we added and cloned in add method above, we can use it to display progress upload of each file using progress method as shown below. To track progress of all (global) upload events, we can use progressall method.
JQUERY
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
fi.on('fileuploadprogress', function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); if (data.context) { data.context.each(function () { $(this).find('.progress').attr('aria-valuenow', progress).children().first().css('width',progress + '%').text(progress + '%'); }); } });

Successful Upload

On successful ajax request, server returns JSON response, to capture these data, we use done callback, which is the equivalent to the success callback provided by jQuery ajax().
JQUERY
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
fi.on('fileuploaddone', function (e, data) { // invoke callback method on success $.each(data.result.files, function (index, file) { //loop though each file if (file.url){ //successful upload returns a file url var link = $('<a>') .attr('target', '_blank') .prop('href', file.url); $(data.context.children()[index]).addClass('file-uploaded'); $(data.context.children()[index]).find('canvas').wrap(link); //create a link to uploaded file url $(data.context.children()[index]).find('.file-remove').hide(); //hide remove button var done = $('<span class="text-success"/>').text('Uploaded!'); //show success message $(data.context.children()[index]).append(done); //add everything to data context } else if (file.error) { var error = $('<span class="text-danger"/>').text(file.error); //error text $(data.context.children()[index]).append(error); //add to data context } }); });

PHP Upload Handler

Blueimp File uploader comes with file upload handler for different server platform. If you are using different platform you can find these handler at their Github Repo. For this tutorial we will be using PHP file upload handler (UploadHandler.php). All we need to do is include the file in our upload PHP script and it takes care of everything. We just need to provide parameters as per our requirement.
PHP
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
require('UploadHandler.php'); $upload_dir = '/home/path/to/uploads/folder/'; $upload_handler = new UploadHandler(array( 'max_file_size' => 1048576, //1MB file size 'image_file_types' => '/\.(gif|jpe?g|png|mp4|mp3)$/i', 'upload_dir' => $upload_dir, 'upload_url' => 'http://localhost/multi_file_upload/uploads/', 'thumbnail' => array('max_width' => 80,'max_height' => 80) ));

Conclusion

Creating custom uploader with Blueimp file upload plugin is really effortless, because you spend less time correcting errors and more time designing user interface, what else can one ask for. You can find everything included in downloadble file below, blueimp plugin is also included in the package, just don't forget to checkout demo and give your valuable feedback, good luck!
Download Demo
New question is currently disabled!