AJAX style multiple images upload using HTML5, JSON and jQuery

You might have seen at many places like Facebook or even in wordpress editor – “Add Media” section, you could upload multiple images without refreshing the page. After image upload, you could immediately see images preview.

multiple-upload-screenshot

How HTML5 multiple images upload works?

HTML5 provides multiple attributes to select multiple file in input file element.

<form action="multi_files.php" target="hidden_iframe" enctype="multipart/form-data" method="post">
 <input type="file" multiple name="upload_files[]" id="upload_files">
</form>

So now you can select multiple files when upload dialog popups up.

Basic HTML5 Setup for multiple images upload

First of all, We’ll hide all elements and use a <button> called “Upload”. It’ll opens up images upload dialog box. Then, once user select files code will auto-submit <form> into <iframe> which calls server side uploading script and upload files.

<div id="upload_form" class="hide">
  <form action="multi_files.php" target="hidden_iframe" enctype="multipart/form-data" method="post">
    <input type="file" multiple name="upload_files[]" id="upload_files">
  </form>
</div>

<div  align="center" style="padding:10px">

  <button onclick="Uploader.upload();" class="btn btn-primary btn-lg">
    Upload Files
  </button>
  <div id="wait" class="hide">
    <img src="upload-indicator.gif" alt="">
  </div>
</div>

<div>
  <iframe name="hidden_iframe" id="hidden_iframe" class="hide">
  </iframe>
</div>

<div id="uploaded_images" align="center">

</div>

Now jQuery Code to trigger uploadbox and start uploading using above hidden iframe.

// this code will open upload dialog box
function showUploadDialog() {
    $('#upload_files').trigger('click');
}
// this code will submits form after files have been selected 
$('#upload_files').on('change', function () {
    $('#upload_files').parent('form').submit();
});

So, once form is submitted backend script PHP, python, jsp, .NET whatever handles it and send response back in JSON format.

Success Responses:- list of files uploaded.

[   "/uploads/DSC00291.JPG",
    "/uploads/DSC00297.JPG",
    "/uploads/DSC00301.JPG",
    "/uploads/DSC00303.JPG"
]

Error Responses:

{
    "error": "Sorry, only images are allowed to upload"
}

Code to send and handle this JSON response.

within upload iframe, following javascript code will call parent frame’s uploadDone function

window.parent.uploadDone('<?php echo json_encode($images); ?>');

uploadDone function to handle this response and render images.

function uploadDone(data) {
    data = JSON.parse(data);
    if (typeof (data['error']) != "undefined") {
        $('#uploaded_images').html(data['error']);
        $('#upload_files').val("");
        return;
    }
    var divs = [];
    for (i in data) {
        divs.push("<div><img src='" + data[i] + "' height='100' class='img-thumbnail'></div>");
    }
    $('#uploaded_images').html(divs.join(""));
    $('#upload_files').val("");
}

Above code will check, if error is sent then error will be displayed otherwise images will be rendered below upload button.

PHP code to handle multiple-upload at server side.

<?php
$failed = false;
$images = Array();
$upload_dir = "UPLOAD_DIR_PATH";

if ($_SERVER['CONTENT_LENGTH'] < 8380000) {
if (isset($_FILES['upload_files']) && $_FILES['upload_files']['error'] != 0) {    

        foreach($_FILES['upload_files']['tmp_name'] as $key=>$value) {

                $file = $_FILES['upload_files']['name'][$key];
                // allow only image upload
                if(preg_match('#image#',$_FILES['upload_files']['type'][$key])) {
                    if(!move_uploaded_file($value, $upload_dir.$file)) {
                        $failed = true;
                    } else {                    
                        $images[] = "WEBSERVER_UPLOAD_DIR_PATH".$file;                    
                    }    
                } else {
                    $images = array("error"=>"Sorry, only images are allowed to upload");
                }
        }
}
} else {
    $images = array("error"=>"Sorry, Upload size exceed allowed upload size of 8MB");
}
if($failed == true) {
	$images = array("error"=>"Server Error<br/>Reported to Admin");
}
?>

<html>
 <body>
  <script type="text/javascript">
  window.parent.Uploader.done('<?php echo json_encode($images); ?>');
  </script>
 </body>
</html>

Finally making javascript more modular and non-sucking with closures that doesn’t conflict with global scope.

Writing Upload object with file upload functions.

var Uploader = (function () {

        jQuery('#upload_files').on('change', function () {
            jQuery("#wait").removeClass('hide');
            jQuery('#upload_files').parent('form').submit();
        });

        var fnUpload = function () {
            jQuery('#upload_files').trigger('click');
        }

        var fnDone = function (data) {

            var data = JSON.parse(data);
            if (typeof (data['error']) != "undefined") {
                jQuery('#uploaded_images').html(data['error']);
                jQuery('#upload_files').val("");
                jQuery("#wait").addClass('hide');
                return;
            }
            var divs = [];
            for (i in data) {
                divs.push("<div><img src='" + data[i] + "' style='height:100px' class='img-thumbnail'></div>");
            }
            jQuery('#uploaded_images').html(divs.join(""));
            jQuery('#upload_files').val("");
            jQuery("#wait").addClass('hide');
        }

        return {
            upload: fnUpload,
            done: fnDone
        }

    }());
Total
0
Shares
Previous Post

Form auto-submission tips for jQuery

Next Post

JavaScript job interview question – Find first non repeated character in string

Related Posts