28

I am trying to capture ajax request`s progress. I am following article from this link http://www.dave-bond.com/blog/2010/01/JQuery-ajax-progress-HMTL5/.

It is not working as expected. Div with id progressCounter should have something in it with % as far as i understand it but nothing happens in my case. Any Help ?

It seems to me like if (evt.lengthComputable) { is not working in XHR

JSFIDDLE: http://jsfiddle.net/bababalcksheep/r86gM/

HTML:

<div id="progressCounter"></div><br>
<div id="loading">Loading</div><br>
<div id="data"></div>

JS:

var progressElem = $('#progressCounter');
var URL = "https://api.github.com/users/mralexgray/repos";
$("#loading").hide();
// write something in #progressCounter , later will be changed to percentage
progressElem.text(URL);

$.ajax({
    type: 'GET',
    dataType: 'json',
    url: URL,
    cache: false,
    error: function (xhr, ajaxOptions, thrownError) {
        alert(xhr.responseText);
        alert(thrownError);
    },
    xhr: function () {
        var xhr = new window.XMLHttpRequest();
        //Download progress
        xhr.addEventListener("progress", function (evt) {
            if (evt.lengthComputable) {
                var percentComplete = evt.loaded / evt.total;
                progressElem.html(Math.round(percentComplete * 100) + "%");
            }
        }, false);
        return xhr;
    },
    beforeSend: function () {
        $('#loading').show();
    },
    complete: function () {
        $("#loading").hide();
    },
    success: function (json) {
        $("#data").html("data receieved");
    }
});
django
  • 2,809
  • 5
  • 47
  • 80
  • try to write your code inside $(documnt.ready(function({//yourcode})) – Osama Jetawe Mar 19 '14 at 10:45
  • 1
    still does not work.http://jsfiddle.net/bababalcksheep/r86gM/8/ – django Mar 19 '14 at 10:48
  • this code is working at http://uksnow.tombh.co.uk/ if you look at http://uksnow.tombh.co.uk/main.js file.. – django Mar 19 '14 at 10:49
  • what error type you have, are you looking at your firebug console errors , are you add the jquery library in your file – Osama Jetawe Mar 19 '14 at 11:04
  • yes, i have jquery in header, and div with id="progressCounter" whould have 100% as text after it is finished but I dont get this div updated as no XHR operation was done. – django Mar 19 '14 at 11:09
  • I found the problem. evt.lengthComputable is not computable but why ? – django Mar 19 '14 at 11:15
  • Check out this plugin to work easily with progress events at ajax requests https://github.com/likerRr/jq-ajax-progress – likerRr Aug 28 '15 at 13:42

3 Answers3

29

ProgressEvent.lengthComputable

The ProgressEvent.lengthComputable read-only property is a Boolean flag indicating if the resource concerned by the ProgressEvent has a length that can be calculated. If not, the ProgressEvent.total property has no significant value.

So in your case if you debug a little , you will find evt.lengthComputable = false; so you can not trace the progress;

    xhr.addEventListener("progress", function (evt) {
        console.log(evt.lengthComputable); // false
        if (evt.lengthComputable) {
            var percentComplete = evt.loaded / evt.total;
            progressElem.html(Math.round(percentComplete * 100) + "%");
        }
    }, false);

DEMO


FYI

If lengthComputable is false within the XMLHttpRequestProgressEvent, that means the server never sent a Content-Length header in the response.

Deepak Ingole
  • 14,912
  • 10
  • 47
  • 79
  • yes, that is it.But can you specify why ```evt.lengthComputable``` is ```false``` in my case.If I use a link to local json file, I get 100% string.If i use demo string ```"https://api.github.com/users/mralexgray/repos"```, it does not work.Why is that ? – django Mar 19 '14 at 11:37
  • I have a server which returns jsons on requests.What can i do to make sure that when i will call it with ajax, i have lengthComputable json returned.I am confused here. – django Mar 19 '14 at 11:40
  • coz your resource does not have computable length. You might also be interested in [Compatibility](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent.lengthComputable#AutoCompatibilityTable) – Deepak Ingole Mar 19 '14 at 11:40
  • Ahh ok.Content length was the problem.Thankx. – django Mar 19 '14 at 11:43
  • glad to help you my friend @django – Deepak Ingole Mar 19 '14 at 11:58
  • One more question. is ProgressEvent cross browser? I see this link ```https://gist.github.com/Xeoncross/7663273```. is there any better solution for it to make it cross browser ? – django Mar 19 '14 at 12:06
  • 2
    @django No ..its not supported in all browser..you can check [here](https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent.lengthComputable#AutoCompatibilityTable) – Deepak Ingole Mar 19 '14 at 12:12
  • What is your current experience in Chrome? (according to https://developer.mozilla.org/en-US/docs/Web/API/ProgressEvent/lengthComputable#Browser_compatibility this is now not crossbrowser? – jave.web Feb 02 '17 at 00:30
0

FOR PHP

if (evt.lengthComputable) { is not working in XHR, I did this and now it is working.

PHP:

$startTime = time(); 
//your code or 
sleep(10); 
$endTime = time() - $startTime; 
header('Content-Length: '.strlen($endTime));
$response['success'] = true;
echo json_encode($response);

Here is my HTML:

<div class="progress">
<div id="bulk-action-progbar" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="1" aria-valuemin="0" aria-valuemax="100" style="width:1%">                 
</div>
</div>

Ajax:

var percentComplete = 1;
$.ajax({
    method: 'post',
    url: 'test.php',
    data:{'actionPerform':'actionPerform'},
    xhr: function(){
          var xhr = new window.XMLHttpRequest();
          //Upload progress, request sending to server
          xhr.upload.addEventListener("progress", function(evt){
            console.log("in Upload progress");
            console.log("Upload Done");
          }, false);
          //Download progress, waiting for response from server
          xhr.addEventListener("progress", function(e){
            console.log("in Download progress");
            if (e.lengthComputable) {
              //percentComplete = (e.loaded / e.total) * 100;
              percentComplete = parseInt( (e.loaded / e.total * 100), 10);
              console.log(percentComplete);
              $('#bulk-action-progbar').data("aria-valuenow",percentComplete);
              $('#bulk-action-progbar').css("width",percentComplete+'%');

            }
            else{
                 console.log("Length not computable.");
            }
          }, false);
          return xhr;
    },
    success: function (res) {
        //...
    }
});
Community
  • 1
  • 1
Muhammad Shahzad
  • 9,340
  • 21
  • 86
  • 130
-4

A simple roundabout of handling this could be the following.

$(document)
    .ajaxStart(
        function() {

            $
                .blockUI({
                    message : '<img src="img/loadajax.gif" title="Loading..">Loading...',
                    css : {
                        padding : 20,
                        margin : 5,
                        width : '30%',
                        top : '40%',
                        left : '35%',
                        textAlign : 'center',
                        color : '#000',
                        border : 'none',
                        backgroundColor : '#fff',
                        cursor : 'wait'
                    }
                });
            });

$(document).ajaxStop(function() {
    $.unblockUI();
});

Just give the path of the GIF that you want to show in the image src. Add this code at the onload of your page or common layout/jsp or header file to run everywhere for all ajax calls

SuperBiasedMan
  • 9,814
  • 10
  • 45
  • 73
rajan
  • 19
  • 2