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.

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.

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.

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.

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.

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().

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.

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

  1. thanks for your script…. may i download it ?

     Reply
  2. Thanks, this script is very useful for my web

     Reply
  3. Please tell me why image resize didn’t work in IE8 IE9 ?
    I cant understand why… i downloaded archive from original project web site, and more others…. end some result… Upload with IE8 IE9 image have some size… without resizing…
    Who can resolve my problem ??? plssss hellppp

     Reply
  4. Hi, the script work fine :)
    But I have a problem….
    I must upload only txt file….
    once uploaded the txt file I have to read it line by line and load a database in mysql.
    How can I change the upload.php or the uploadhandler.php file
    to load the database ?
    Thanks
    P.S. sorry form my english …. :)

     Reply
  5. plugin that I was looking, and the script works fine. suport with the latest version of wordpress. Thank you very much :)

     Reply
  6. how do I rename the uploaded files?

     Reply
  7. how to insert image in mysql bd before files uploaded??

     Reply
  8. Hi! When I move/include the ‘mark up’ i.e html part to another folder/file it does not work even after making necessary changes in the code. It throws error data.submit() is not a function. Please let me know if you know the fix.

     Reply
  9. Thanks, this script is very useful.

     Reply
  10. how do I rename the uploaded files?

     Reply
  11. Hi,

    Have you thought about the “upload all” function ?

    Securing upload.php with some postvar might be an idea also. Please update and keep this good script flowing.

     Reply
  12. This is good. Very useful script.

     Reply
  13. Hi, i can send dinamic data(id) to insert file name to database,but i can’t to get file name for loading files with the same id,can you help me?
    thanks!

     Reply
    • Hi,

      Did you resolved this ? I’m reviewing the code of blueimp itself for SQL upload but I’m not sure if this can be done the same way.

      Thanks!

  14. This is great, thanks for that!
    But now this is based for images, can’t we add .txt files, etc ? I’m not sure here how to accomplish that

     Reply
  15. Is there a warning available, before upload, if someone selects a file over the maximum allowed?

     Reply
  16. Hi, this script is very useful, this script is only creating one thumbnail, and i want to create more thumbnail, then please tell me how to do that.

    thank you.

     Reply
Message Type : Question Comment ?
  • Question : Can include code, jsFiddle, codePen etc using Markdown Syntax.
  • Comment : Short comments and questions.