6

I want to display a progress bar when I click on a button to load content through ajax. As soon as I create the $.ajax call, the communication goes to a php file on the server which scrapes data from another file on the server. And it takes a good 7-8 seconds to bring in the data.

I want to display a progress loader at the time of making the ajax request. I was looking on the internet and couldnt find a simple solution. All I could find were complex upload file scripts which would take an awful while to customize to perform this simple operation. If anybody can help, that'd be great. Else I'd have to make do with the spinner.

amit
  • 10,133
  • 22
  • 72
  • 121
  • 1
    How can you create a progress bar if you have 1 request that returns the data? You can create a progress bar if you had multiple requests and if each request gave you a status update about the total percentage of data loaded. What you can do is create a spinner that goes away once the data is loaded. – N.B. Sep 28 '12 at 10:15
  • the number of requests can be manipulated. all i am looking for is a step in the right direction. – amit Sep 28 '12 at 10:18
  • 5
    This operation isn't simple at all - to get the current progress your php script would need to set a (session) variable containing the percentage of work done, which you would need to constantly poll via ajax and update your progress display accordingly. So at least you need another php script (the backend for polling the progress), an ajax accessor for that, and a script for displaying and updating a progress bar. – l4mpi Sep 28 '12 at 10:18
  • 1
    You can't know how long a request is going to take. It depends on the request speed, load speed etc. Arun David's option is the best one possible. – Deep Frozen Sep 28 '12 at 10:18
  • If you had, say, 5 $.ajax requests that are to be executed in succession - you could implement the progress bar. You'd have total of 5 items, in every item's `success` function you'd add +20% to the element displaying the progress bar. It's not difficult if you have the data that allows you to construct such a feature. But since you haven't given us the details, it's difficult to point you to a right direction. – N.B. Sep 28 '12 at 10:20
  • @l4mpi: I understand the concept. Is there a tutorial? – amit Sep 28 '12 at 10:20
  • Possible duplicate : http://stackoverflow.com/questions/2474528/showing-progressbar-progress-with-ajax-request – totten Sep 28 '12 at 10:21
  • 1
    @amit http://www.redips.net/javascript/ajax-progress-bar/ I think means something like this – EaterOfCode Sep 28 '12 at 10:21
  • @EaterOfCorpses, no he do not. – totten Sep 28 '12 at 10:26
  • @amit the link EaterOfCorpses posted seems like a good starting point. Of course you need to change the example php script to print a session variable containing the progress and set this to a correct value in your main php script. But the task of computing the current progress can be rather hard itself if you're not just doing something simple like loading a file with a known size from somewhere... – l4mpi Sep 28 '12 at 10:30
  • total round trip time for the request vary on each request so how can you show the progress .:) – Arun Killu Sep 29 '12 at 06:56

5 Answers5

3

Because all other answers are just about showing a placeholder image or text or just faking it, here's how you could do it (just a description, no code - but the only hard part is determining how much of the work is actually done):

Edit the php script you call via $.ajax to calculate the percentage of work it has completed - how you would do this is extremely dependend on the tast the script does and as such can be extremely easy (for example, when you're just iterating over an array of things to process which each take about the same time) or extremely hard (e.g. when most of the time is spent in one single, non-repeating call to a library or built-in function). Save this percentage in a session variable:

$_SESSION["PERCENTAGE_DONE"] = $my_calculated_percentage;

Obviously, you want to update this variable as often as is possible and reasonable.

Now, create another php script which just prints out this value (plaintext would be enough for this example, but you could also use json or xml or some other format you like):

//initialize session, set headers etc. before this
echo $_SESSION["PERCENTAGE_DONE"]

For the javascript part, create another function that calls the new php script via ajax, reads the returned value and draws / updates the progress bar (for the drawing part you could take JustinJohns answer as a starting point). Now, after you execute the main $.ajax call, use this function with setTimeout to query the server repeatedly until the task is finished.

l4mpi
  • 5,103
  • 3
  • 34
  • 54
  • the problem I see in this code is that start_session blocks as long as a different script called start_session with the same session id and in Chrome you cant have 2 ajax calls at the same time chrome will wait till the first is completed and go then to the next – EaterOfCode Oct 01 '12 at 07:47
  • No idea about the Chrome thing (why would they disallow parallel requests?), but I thought the php session block was not an issue in apache, am I wrong there? Also you could just use start_session and session_write_close immediately before and after setting the session variable, which should unblock the session. – l4mpi Oct 01 '12 at 08:47
  • We had the problem on our server last time here what runs Apache so I think it still does but `session_write_close` should fix it yes and the chrome thingy is yeah its strange :( – EaterOfCode Oct 01 '12 at 10:33
  • 2
    I may be wrong (and late) but I think its a good idea to use setTimeout and set another timeout on the success of the ajax function so that if there is a slow connection it not gets delayed and wrecked – EaterOfCode Nov 30 '12 at 15:15
0

Please try following script for Ajax progress bar:

<script>
function submit_form_data(){
    $("#preview").html(''); 
    $("#preview").html('<img src="loader.gif" alt="Uploading...."/> <br><p>Please wait for response.............</p>'); 
    $.post('getdata.php',function(data){$("#preview").html(data)}) }
</script>

<div id='preview'></div>
Artemix
  • 2,113
  • 2
  • 23
  • 34
-2

The fundamental problem is that you do not know how long the request is going to take.

This will be suggestion rather than an answer.

I assumed time will be around 7-8 seconds always.

Make progress with loading 10 percentage on each second until 90 percentage attained.

After attaining wait for your ajax request to be completed and make bar width 100 percentage on success callback of ajax.

You can customize with time to load percentage of bar.

Please check this demo

Justin John
  • 9,223
  • 14
  • 70
  • 129
  • Even using a placeholder gif would be better than just faking it... this would only be an option if the processing time is constant or almost constant, and even then it couldn't deal with things like network spikes etc. – l4mpi Sep 28 '12 at 11:13
  • @14mpi I know, our fundamental problem is that you do not know how long the request is going to take. It just a suggestion. The performance of progress bar will certainly depend with processing time. But this will give general idea of progress bar. – Justin John Sep 28 '12 at 11:35
  • @EaterOfCorpses Yes, you are right. I made an edit with your fiddle example. – Justin John Oct 06 '12 at 18:34
-5

The image you used should loading animation image.

<div id="loading" >
<p>
<img src="images/loading.gif">
Please Wait
</p>
</div>

Then in the script function use the following code

<script type='text/javascript'>
function showLoading() {
$("#loading").show();
}

function hideLoading() {
$("#loading").hide();
}

</script>

Then call the showLoading and hideLoading function whereever you need in the ajax call. It will shows and hides the animation.

Mohan Kumar
  • 334
  • 1
  • 4
  • 10
-7

As you have asked for a simple solution, This may help you.. Have a div with ID 'loading' with display as hidden.

<div id='loading' style='display:none;'><img src='loading.gif' /></div>

When the ajax request called, display the div

$('#loading').show();

When the response is success, again hide back the div,

$('#loading').hide();
Arun David
  • 2,714
  • 3
  • 18
  • 18