Show a progress on multiple file upload Jquery/Ajax

Paul Ledger picture Paul Ledger · Apr 22, 2014 · Viewed 82.5k times · Source

I have upload form that allows users to upload multiple files. I decided that a progress bar would be good if the files are quite large. Below is my source code. I am new to jquery normally I would just php but I find that ajax is more user friendly.

<div id="new_upload">
    <div class="close_btn"></div>
    <div id="uploads"></div>
    <form action="global.func/file_upload.php" method="post" enctype="multipart/form-data" id="upload_file">
    <fieldset><legend>Upload an image or video</legend>
    <input type="file" id="file" name="file[]" placeholder="Upload Image or Video" multiple /><input type="submit" value="upload file" id="upload_file_btn" required />
    </fieldset>

    <div class="bar">
        <div class="bar_fill" id="pb">
            <div class="bar_fill_text" id="pt"></div>
        </div>
    </div>

    </form>
</div>
<script>
function OnProgress(event, position, total, percentComplete){    
    //Progress bar
    console.log(total);
    $('#pb').width(percentComplete + '%') //update progressbar percent complete
    $('#pt').html(percentComplete + '%'); //update status text
}
function beforeSubmit(){
    console.log('ajax start');
}
function afterSuccess(data){
    console.log(data);
}
$(document).ready(function(e) {
    $('#upload_file').submit(function(event){
        event.preventDefault();
        var filedata = document.getElementById("file");
        formdata = new FormData();
        var i = 0, len = filedata.files.length, file;
         for (i; i < len; i++) {
            file = filedata.files[i];
            formdata.append("file[]", file);
        }
        formdata.append("json",true);
        $.ajax({
            url: "global.func/file_upload.php",
            type: "POST",
            data: formdata,
            processData: false,
            contentType: false,
            dataType:"JSON",
            xhr: function() {
                var myXhr = $.ajaxSettings.xhr();
                return myXhr;
            },
            beforeSubmit: beforeSubmit,
            uploadProgress:OnProgress, 
            success: afterSuccess,
            resetForm: true
        });
    });
});
</script>

The image upload works fine, the array send to ajax but the progress bar doesn't move. In fact the console.log for the two functions called need to produce this don't appear either. Is there a correct way to call the functions in my ajax request that would get this progress bar to work.

beforeSubmit: beforeSubmit, uploadProgress:OnProgress, success: afterSuccess,

NOTE that this function 'success: afterSuccess' is working as the console is displaying my data.

Answer

Eskinder picture Eskinder · Nov 20, 2014

This is your HTML form

<form method="post" action="uploadImages.php" name ='photo' id='imageuploadform' enctype="multipart/form-data">
        <input hidden="true" id="fileupload" type="file" name="image[]" multiple >

        <div id ="divleft">
            <button id="btnupload"></button>

        </div>    

    </form>

This is your JQuery and ajax. By default the fileInput is hidden.

Upload Button clicked

$("#btnupload").click(function(e) {

    $("#fileupload").click();
    e.preventDefault();

});


$('#fileupload').change(function (e) {

    $("#imageuploadform").submit();
    e.preventDefault();

});

$('#imageuploadform').submit(function(e) {

    var formData = new FormData(this);

    $.ajax({
        type:'POST',
        url: 'ajax/uploadImages',
        data:formData,
        xhr: function() {
                var myXhr = $.ajaxSettings.xhr();
                if(myXhr.upload){
                    myXhr.upload.addEventListener('progress',progress, false);
                }
                return myXhr;
        },
        cache:false,
        contentType: false,
        processData: false,

        success:function(data){
            console.log(data);

          alert('data returned successfully');

        },

        error: function(data){
            console.log(data);
        }
    });

    e.preventDefault();

});


function progress(e){

    if(e.lengthComputable){
        var max = e.total;
        var current = e.loaded;

        var Percentage = (current * 100)/max;
        console.log(Percentage);


        if(Percentage >= 100)
        {
           // process completed  
        }
    }  
 }

Your php code looks like this

<?php

header('Content-Type: application/json');

       $valid_exts = array('jpeg', 'jpg', 'png', 'gif'); // valid extensions
        $max_size = 30000 * 1024; // max file size in bytes

        $json = array();

            if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
            {
                for($i=0;$i<count($_FILES['image']['tmp_name']);$i++)
                {
                    $path="image/uploads/photos/";

                    if(is_uploaded_file($_FILES['image']['tmp_name'][$i]) )
                    {
                      // get uploaded file extension
                      $ext = strtolower(pathinfo($_FILES['image']['name'][$i], PATHINFO_EXTENSION));
                      // looking for format and size validity
                          if (in_array($ext, $valid_exts) AND $_FILES['image']['size'][$i] < $max_size)
                          {
                                  // unique file path
                                  $uid = uniqid();
                                  $date = date('Y-m-d-H-i-s');
                                  $path = $path ."image_" .$date. '_' . $uid . "." .$ext;

                                  $returnJson[]= array("filepath"=>$path);

                                  $filename = "image_" . $date . "_" .$uid . "." . $ext;
                                  $this->createthumb($i,$filename);

                                    // move uploaded file from temp to uploads directory
                                  if (move_uploaded_file($_FILES['image']['tmp_name'][$i], $path))
                                  {
                                    //$status = 'Image successfully uploaded!';
                                      //perform sql updates here

                                  }
                                  else {
                                    $status = 'Upload Fail: Unknown error occurred!';
                                  }


                          }
                          else {
                            $status = 'Upload Fail: Unsupported file format or It is too large to upload!';
                          }
                    }
                    else {
                      $status = 'Upload Fail: File not uploaded!';
                    }
                }
              }
            else {
              $status = 'Bad request!';
            }


            echo json_encode($json);

?>