Facebook

Monday, November 28, 2016

Mysqli Bind dynamic parametere

Trying to create a function to insert data into a SQL table, using MySQLI. I want to create a generic function, to insert different types of data in different databases.
The issue is at binding the parameters. I can't find a good way to bind them, as I've got multiple variables with values and keys, but they're all in array format, and  bind_param  requires a new variable for each
$sql = 'SELECT id, lastname FROM customers WHERE ' .
  'category = ? AND ' .
  'lastname LIKE ?';

/* Prepare statement */
$stmt = $conn->prepare($sql); if($stmt === false) {
  trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->errno . ' ' . $conn->error, E_USER_ERROR);
}
 
$category_id = 1;
$lastname = '%Smith%';
 
/* Bind parameters. Types: s = string, i = integer, d = double,  b = blob */
$stmt->bind_param('is', $category_id, $lastname);
 
/* Execute statement */
$stmt->execute();
 
/* Fetch result to array */
$res = $stmt->get_result();
while($row = $res->fetch_array(MYSQLI_ASSOC)) {
  array_push($a_data, $row);
}
The problem
$stmt->bind_param() does not accept params array. So, how to bind params, if their number is variable, depending on user input in your application?

A workaround is to use call_user_func_array to pass dynamically the params array.

The solution
In the following code:

  • $conn is the connection object
  • $a_bind_params is the array of the parameters you want to bind
  • $a_param_type is an array with the type of each parameter (Types: s = string, i = integer, d = double, b = blob). This is another disadvantage of MySQLi API. You have to maintain this array some way in your application.
  • With call_user_func_array, array params must be passed by reference. See notes in manual page.

  • The code:

    /* Bind parameters. Types: s = string, i = integer, d = double,  b = blob */
    $a_params = array();
     
    $param_type = '';
    $n = count($a_param_type);
    for($i = 0; $i < $n; $i++) {
      $param_type .= $a_param_type[$i];
    }
     
    /* with call_user_func_array, array params must be passed by reference */
    $a_params[] = & $param_type;
     
    for($i = 0; $i < $n; $i++) {
      /* with call_user_func_array, array params must be passed by reference */
      $a_params[] = & $a_bind_params[$i];
    }
     
    /* Prepare statement */
    $stmt = $conn->prepare($sql);
    if($stmt === false) {
      trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->errno . ' ' . $conn->error, E_USER_ERROR);
    }
     
    /* use call_user_func_array, as $stmt->bind_param('s', $param); does not accept params array */
    call_user_func_array(array($stmt, 'bind_param'), $a_params);
     
    /* Execute statement */
    $stmt->execute();
     
    /* Fetch result to array */
    $res = $stmt->get_result();
    while($row = $res->fetch_array(MYSQLI_ASSOC)) {
      array_push($a_data, $row);
    }

    Monday, October 24, 2016

    PHP mailer - debug example

    require_once('../class.phpmailer.php');
    //include("class.smtp.php"); // optional, gets called from within class.phpmailer.php if not already loaded
    
    $mail             = new PHPMailer();
    
    $body             = file_get_contents('contents.html');
    $body             = eregi_replace("[\]",'',$body);
    
    $mail->IsSMTP(); // telling the class to use SMTP
    $mail->Host       = "mail.yourdomain.com"; // SMTP server
    $mail->SMTPDebug  = 2;                     // enables SMTP debug information (for testing)
                                               // 1 = errors and messages
                                               // 2 = messages only
    $mail->SMTPAuth   = true;                  // enable SMTP authentication
    $mail->Host       = "mail.yourdomain.com"; // sets the SMTP server
    $mail->Port       = 26;                    // set the SMTP port for the GMAIL server
    $mail->Username   = "yourname@yourdomain"; // SMTP account username
    $mail->Password   = "yourpassword";        // SMTP account password
    
    $mail->SetFrom('name@yourdomain.com', 'First Last');
    
    $mail->AddReplyTo("name@yourdomain.com","First Last");
    
    $mail->Subject    = "PHPMailer Test Subject via smtp, basic with authentication";
    
    $mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
    
    $mail->MsgHTML($body);
    
    $address = "whoto@otherdomain.com";
    $mail->AddAddress($address, "John Doe");
    
    $mail->AddAttachment("images/phpmailer.gif");      // attachment
    $mail->AddAttachment("images/phpmailer_mini.gif"); // attachment
    
    if(!$mail->Send()) {
      echo "Mailer Error: " . $mail->ErrorInfo;
    } else {
      echo "Message sent!";
    }
        

    Wednesday, September 7, 2016

    Implement multi file upload using blueimp library

    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -----------HTML ------------- ---------- ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>

    <!-----Image preview area------> <div class="row fileThumbnails">
       <div class="small-2 columns preview hide">
          <img src="#" class="preview-img">
          <button class="cancel" id="" name=""><i class="fa fa-times" aria-hidden="true"></i></button>
       </div>

    </div>
    --- ------------- -----------JAVASCRIPT ----------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })
    Drop and Drop Files Here
    If you want to do some customization in the interface, behaviour etc., I have an example.
    I customised the behaviour as per below requirements.
    Requirement:
    Interface: 
    Create a file selector, 
    That can select multiple files, 
    On selecting files, start uploading images
    Show a single progress bar
    Display a thumbnail of files selected with a contol(may be a cancel button) near to thumbnail preview to cancel upload of that image only

    Blueimp project: https://blueimp.github.io/jQuery-File-Upload/

    ------ ------------- -------------HTML ------------- ------------ ------
    <div id="mulitplefileuploader">
    <div class="ajax-upload-dragdrop text-center">
    <div class="columns small-12">Drop and Drop Files Here</div>
    <div class="columns small-12 drop-drop-img"><img src="{{dragDropURL}}" /></div>
    <div class="columns small-12 medium-6 explicit-small-centered upload-multi-files-button">
    <label for="fileupload" class="button-alert button expanded">
    <img src="{{ uploadIconURL }}"  /> Upload Files
    </label>
    <input id="fileupload" type="file" name="files[]" multiple />
    </div>
    </div>
    </div>
    --- ------------- -------------JAVASCRIPT ------------- ------------ ---
    $(document).ready(function () {
    $('#fileupload').fileupload({
    // This function is called when a file is added to the queue
    add: function (e, data) {

    //This area will contain file list and progress 
    var reader = new FileReader();
    reader.onload = function (e) {
    data.context = data.files[0].name;
    console.log(e.target);
    var imgWrap = $('.fileThumbnails .preview.hide').clone(true);
    $(imgWrap).attr('data-file-name', data.files[0].name);
    $(imgWrap).removeClass('hide').find('img').attr('src', e.target.result);
    $(".fileThumbnails").prepend(imgWrap);
    imgWrap.find('.cancel').click(function () {
    if (!imgWrap.hasClass('finished')) {
    jqXHR.abort();
    imgWrap.remove();
    }
    imgWrap.fadeOut(function () {
    imgWrap.remove();
    });
    });
    }
    reader.readAsDataURL(data.files[0]);

    // Automatically upload the file once it is added to the queue
    var jqXHR = data.submit()
    .success(function (result, textStatus, jqXHR)
    {
    //imgWrap.remove();
    var data = JSON.parse(result);
    //console.log(data);
    //console.log(data.fileName);
    if ($.trim($("#grid-container").html()) == "") {
    $("#main-grid-container").html('<div class="row grid grid-margin" id="grid-container">' + data.html + '</div>');
    } else {
    var Items = parseInt($("#totalMediaItems").html());
    Items += 1;
    $("#totalMediaItems").html(Items);
    $("#grid-container").prepend(data.html);

    $(".item-orders").each(function (index, element) {
    $(this).html(index + 1)
    });

    }
    $("[data-file-name='" + data.fileName + "']").remove();
    if ($("[data-file-name]").length == 0)
    {
    $('#progress .ajax-file-upload-progress').css(
    'width',
    '0%'
    ).html('');
    }
    })
    .error(function (jqXHR, textStatus, errorThrown) {/* ... */})
    .complete(function (result, textStatus, jqXHR) {/*....*/});
    },
    start: function (e) {
    $(".ajax-file-upload-container").removeClass('hide');
    },
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .ajax-file-upload-progress').css(
    'width',
    progress + '%'
    ).html(progress + '%');
    }
    });
    //Helper function for calculation of progress
    function formatFileSize(bytes) {
    if (typeof bytes !== 'number') {
    return '';
    }

    if (bytes >= 1000000000) {
    return (bytes / 1000000000).toFixed(2) + ' GB';
    }

    if (bytes >= 1000000) {
    return (bytes / 1000000).toFixed(2) + ' MB';
    }
    return (bytes / 1000).toFixed(2) + ' KB';
    }
    })