0

I want to update a progress bar (bootstrap) while a PHP page is processing from an AJAX GET request.

Currently the progress bar updates AFTER the AJAX request is 100% complete. The pages have a lot more content than what's listed, but this is the basics on what needs to get functional.

Main PHP Page

<html><head>
<script type="text/javascript">
function updateBar(i)
{
  $('#updateBar').html('<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: '+i+'%;">'+i+'</div>');
}
</script>
</head>
<body>
<?
echo "<button class='btn btn-success' id='button'>Process</button>";
echo "<div class='progress' id='updateBar'>Loading...</div>";
echo "<div id='update'></div>";
?>
<script>
$(document).ready(function () {
  $("#button").click(function(){
    $("#update").text("Loading...");
    $.ajax({
      type: "GET",
      url: "ajaxPHP",
      success: function(data){
        $("#update").html(data);
      },
      error: function(xhr, status, error) {
        alert(xhr.responseText);
      }
    });
  });
});
</script>

AJAX PHP Page (ajaxPHP):

$max=85;
for($i=0;$i>=$max;$i++){
// HERE ARE A BUNCH OF CURL CALLS AND SERVER SIDE PROCESSING, TAKING ABOUT 30 SECONDS PER LOOP
?> 
<script>
  var num = "<?php echo $i; ?>";
  var max = "<?php echo $max; ?>";
  var i = num/max;
  updateBar(i);
</script>
<?
} 
Andrew
  • 4,443
  • 5
  • 33
  • 75
  • Is that javascript even valid? You're re-declaring the same global vars over and over with `var`...although you could run this Javascript with `eval` (if you get rid of the ` – developerwjk Dec 23 '14 at 17:49
  • I think that your script is very aggresive. You are doing 85 calls to updateBar very fast. You should move your loop logic to the ajax call. – sbaglieri Dec 23 '14 at 17:51
  • I think it is, can you give me an example on what you're referring to? – Andrew Dec 23 '14 at 17:51
  • Also each one of my loops takes about 30 seconds of CURL calls and server side processing. So it's not as bad as it looks. – Andrew Dec 23 '14 at 17:51
  • If this is for a loading bar, your javascript doesn't make sense. What this will do is update the bar quickly from 0 to 85, by hitting every value in between, AFTER everything is already done. The user won't really see a loading bar. – developerwjk Dec 23 '14 at 17:53
  • Wait a moment, you are calling ajaxPHP only once – sbaglieri Dec 23 '14 at 17:53
  • That's correct. Click one button and start processing everything that needs to be processed. While hopefully giving the user an update on what's going on in the background rather than a loading spinner forever. – Andrew Dec 23 '14 at 17:54
  • You have to do period Ajax calls to a page that just returns what percent is complete and update the bar, not do one call to the operation that you're running. Because as you have it, the bar just jumps to the end. – developerwjk Dec 23 '14 at 17:54
  • You have to do multiple calls to ajaxPHP! returning the progress state. Sorry for my english but developerwjk can explain the idea better than me :P – sbaglieri Dec 23 '14 at 17:56

1 Answers1

1

You'll want to trigger recurring AJAX calls until your script is completed. Something like:

var getStatus = function() {
    $.ajax({
      type: "GET",
      url: "ajaxPHP",
      success: function(data){
        $("#update").html(data);
        if (data!=100) { // examine the response to determine if the server is done
            setTimeout(getStatus, 1000); //delay next invocation by 1s
        }
      },
      error: function(xhr, status, error) {
        alert(xhr.responseText);
      }
    });
};

$(document).ready(function () {
  $("#button").click(function(){
    $("#update").text("Loading...");
    getStatus(); //initiate job and start polling
  });
});
pherris
  • 17,195
  • 8
  • 42
  • 58