2

I have an upload form that uses AJAX to pass the data to a PHP process file to process the uploading etc. I am trying to add a progress bar to my form while the file is being uploaded.

I have tried a few snippets of code that i have found by searching around but they just don't seem to work. Have tried multiple variations of the following:

$.ajax({
xhr: function () {
    var xhr = new window.XMLHttpRequest();
    xhr.upload.addEventListener("progress", function (evt) {
        if (evt.lengthComputable) {
            if (evt.lengthComputable) {
                var percentComplete = evt.loaded / evt.total;
                $('.progress').css({
                    width: percentComplete * 100 + '%'
                });
                if (percentComplete === 1) {
                    $('.progress').addClass('hide');
                }
            }
        }
    }, false);

    xhr.addEventListener("progress", function (evt) {
        if (evt.lengthComputable) {
            var percentComplete = evt.loaded / evt.total;
            $('.progress').css({
                width: percentComplete * 100 + '%'
            });
        }
    }, false);

    return xhr;
},
    url: "upload.php",
    type: 'POST',
    data: formData,
    success: function (data) {
        //success
    }
});

None of them seem to work though, i have tried alerting out the percentComplete variable and it is always 100, any help would be appreciated, thanks.

3 Answers 3

11

I hope this helps -

HTML -

<form id="data" method="post" enctype="multipart/form-data">
  <input name="up_vid" type="file" id="up_vid"/>
  <br><br>
  <button id="uploadBtn">Begin Upload</button>
</form>

<br><br>
<div id="status">PROGRESS HERE</div>

JS

$(document).ready(function() {
    $("#uploadBtn").click(function() {
        var formData = new FormData($('#data')[0]);
        console.log(formData);
        $.ajax({
            url: "/echo/html/",
            type: 'POST',
            data: formData,
            xhr: function() {
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener("progress", function(evt) {
                    if (evt.lengthComputable) {
                        var percentComplete = evt.loaded / evt.total;
                        console.log(percentComplete);
                        $('#status').html('<b> Uploading -> ' + (Math.round(percentComplete * 100)) + '% </b>');
                    }
                }, false);
                return xhr;
            },
            success: function(data) {
                $("#status").html('UPLOADED!!');
            },
            cache: false,
            contentType: false,
            processData: false
        });
        return false;
    });
});

Live demo - https://jsfiddle.net/im4aLL/n7hwfoxd/4/

Sign up to request clarification or add additional context in comments.

3 Comments

Could this be a problem with xampp? The live demo works but when copying the exact code over to a file on xampp, it doesn't.
have you changed URL?
@user2460444 It probably is, I am having the same issue.
4

You can try tinker with this working template.

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<style type="text/css">
#progressContainer {
  display: inline-block;
  overflow: hidden;
  width: 400px;
  height: 10px;
  border: 1px solid #333333;
  border-radius: 999px;
}

#progress {
  display: block;
  height: 100%;
  background-color: green;
  border-radius: 999px;
  -o-transition: .1s;
  -ms-transition: .1s;
  -moz-transition: .1s;
  -webkit-transition: .1s;
  transition: .1s;
}
</style>
<div>   
 <form enctype="multipart/form-data" id="form1">
  <input name="file" id="file" type="file" />
  <input type="button" value="Upload" />
 </form>
</div>  
<div id="progress-text1">0%</div>
<span id="progressContainer">
 <span id="progress" style="width:0%;"></span>
</span>
<div id="progress-text2">0%</div>
<div><progress value="0" id="progress1"></progress></div>

<script>
$('#file').on('change', function() {
    $('#progress1').val('0');
});

$(':button').on('click', function() {
    if( $('#file').val() == "" ) {
        alert('Please choose a file before pressing upload..');
        return;
    }
    var FD = new FormData($('#form1')[0]);
    $(FD).serializeArray();

    $.ajax({
        url: 'fileupload-handler.php',
        type: 'POST',
        data: FD,
        cache: false,
        contentType: false,
        processData: false,
        success: function(data){
            alert(data); // Do something with data received
            $('#file').val("");
        },

        // this handles the progress bar
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', function(e) {
                    var percent_loaded = Math.ceil((e.loaded / e.total)*100);
                    $('#progress-text1').text(percent_loaded+'% has been uploaded..');
                    $('#progress-text2').text(percent_loaded+'% has been uploaded..');
                    $('#progress').css('width', percent_loaded + '%');
                    if (e.lengthComputable) {
                        $('progress').attr({
                            value: e.loaded,
                            max: e.total,
                        });
                    }
                } , false);
            }
            return myXhr;
        }
    });
});
</script>

Comments

-2

The solution is very simple. I hope that the ajax request is triggered only when some action is performed, like on a buttons click or some event.

Now, for that particular event, you do need to start the progress bar. Multiple libraries are there. And, end it when the response is received.

So, the code would:

$(document).on("click","#button", function(){
  console.log("Start"); //Start progress bar here
  $.ajax({ 
  "type": "POST",
  "url": "upload.php",
  "success": function()
  {
    console.log("end"); //End progress bar here
  }
 });
});

Hope, the logic is easy enough to understand.

3 Comments

The whole idea of a progress bar is to show the progress. What you have suggested here is more of a "loading" indicator.
@Lix Oh, I got your point. Thanks. Leaving my answer, as it is if it may help someone.
Yeah, this is just confirming the start/end, not a progression.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.