CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

A Simple Web Progress Bar...

Looking for a BusyBox control? Use this one here.
 



Comments

Darrell said:

Brendan - I setup a hidden div like you do but put in some text saying "Request processing..." and set it to blinking. It's a little hokey, but it works. I'm not the GUI master, like you.

I was thinking of adding this as part of a control that inherited from Button so that you could just drag and drop it. But other things seem to keep taking priority. :)
# February 25, 2004 9:30 AM

Brendan Tompkins said:

Jared. Your solution looks good for animating an image before the page loads fully, but most of the time, I need to do the inverse: Show the animation as soon as a form is posted, and before the browser receives the form results. I'm not sure that the way you are loading the image will make any difference... Anyone?
# February 25, 2004 12:55 PM

Brendan Tompkins said:

Darrell,

Yes. Your solution is hokey. ;)
# February 25, 2004 12:57 PM

waish said:

thanx for the solutions,

it's an ugly problem I hung a few hours - how should I know form submit was the evil thing ;()
although not the perfect solution using flash it sure gives some "cross-browser compatibility" ...

greetz,

waish
# March 9, 2004 3:38 AM

Arvind said:

Well, here's a nice and easy solution ... working off of Jared's suggestion:

Basically, what we need to do is reload the image after the form has been submitted. Keep in mind an image is reloaded when it's "src" attribute is assigned a value. So, we need to do the following ...

1. Declare a method for "onsubmit":

function formSubmit()
{
document.myForm.action = "YOUR URL TO SUBMIT";
document.myForm.submit();

// Reload your animated GIF image
if (document.images) document.progressImage.src = document.progressImage.src;

return false; // because we're doing the submit in this method
}

2. Modify your form declaration (make sure you don't leave out the "return" from the onSubmit value):

<form enctype="multipart/form-data" action="" method="post" name="myForm" onSubmit="return formSubmit()">

3. Try it out!!!!

# March 18, 2004 8:23 AM

abc said:

ccccc
# April 19, 2004 4:29 AM

Brendan Tompkins said:

Abc. Thanks for your comments! I'm glad someone's tuned in!
# April 19, 2004 4:35 AM

Paul said:

Thanks. I ran into this problem yesterday. This solution works well.
# April 27, 2004 11:55 AM

me said:

hi
# May 8, 2004 6:56 PM

Warren Hornsby said:

Another solution (to keep the animated gif) is to display the "working" message as a popup window. 3 steps...

(1) Example source of the "main.htm" page...

<html>
<head>
<title>Tester</title>
<script language="JavaScript"><!--
var workingWin;
function showWorking() {
x = screen.availWidth / 2 - 200;
y = screen.availHeight / 2 - 50;
workingWin = window.open("working.htm", "working",
"left=" + x + ",top=" + y +
",height=100,width=400,fullscreen=no,toolbar=no," +
"status=no,menubar=no,scrollbars=no,resizable=no," +
"directories=no,location=no");
}
function clearWorking() {
try {
workingWin.close();
} catch (e) {}
}
// -->
</script>
</head>
<body onunload="clearWorking()">
<form name="frm" method="GET" action="http://www.my.yahoo.com">
<p><input type="button" value="Submit" onclick="showWorking();frm.submit();"></p>
</form>
</body>
</html>

(2) Example source of the popup (named "working.htm" in the same directory as main.htm):

<html>
<head><title>Processing Request</title></head>
<body bgcolor="#336699">
<p align="center"
style="font-family:Arial; font-size:10pt; font-weight:bold; color:white">
<br>Please wait while your request is being processed.<br><br>
<img src="loading.gif"></p>
</body>
</html>

(3) "Borrow" the cool animated gif from this page, saving it as "loading.gif" in the same directory.

The thing I like about this approach is it's easy to plug in the progress bar to any of your existing pages with little fuss -- no changes to the layout, just add the necessary javascript calls.
# May 13, 2004 5:00 AM

John Simone said:

The code submitted by Warren Hornsby here is exquisite ... except for one minor thing: if a user presses enter in a search form (input text box) instead of clicking the "Submit" button to submit their form, s/he will not see the pop-up window. So instead of:

<form name="frm" method="GET" action="http://www.my.yahoo.com">">http://www.my.yahoo.com">
<p><input type="button" value="Submit" onclick="showWorking();frm.submit();"></p>

Use:

<form name="frm" method="GET" action="http://www.my.yahoo.com" onSubmit="showWorking();frm.submit();">
<p><input type="submit" value="Submit"></p>

Note the button type has been changed to "submit" and the onClick call has been eliminted and in its place an onSubmit call has been placed in the form tag.

From my experience, this works like a friggin' charm. Rock on, web brothers and sistahs.
# May 20, 2004 4:52 AM

Brendan Tompkins said:

Wow. This is taking on a life of its own. My problem about the window.open route is that

#1 Popup blockers will not allow this
#2 You get that ugly IE 3D border
#3 If the user click on the page, it will receive focus and send the window to the bg. (show modal may help this, but you'll still have problems #1 and #2.

Just my $.02
# May 20, 2004 4:59 AM

wmas said:

This seems to work...

function showIcon(){
window.setTimeout('showProgress()', 5); }

function showProgress(){
window.document.all.waiticon.src='images/eartharrowWHT.gif'; }
# August 12, 2004 7:47 AM

John said:

Arvind your solution doesn't work with IE 6.0. When you pst the multipart form directly or with javascript method submit(), everything is blocked by IE :-((
I tried to install setTimeout or setInterval nothing works ! Every process in the window seems halted when the form is posted :-(
I tried also with an iframe, same bad thing.

Any solutions other than a popup ?

Tks
John
# August 19, 2004 4:32 AM

Christian Salazar said:

I found this solution...

this part goes in the <head> section:

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
function doSubmit() {
document.all.stuff.style.display = "none"; //hides form
document.all.progress.style.display = "inline"; //unhides gif animation
document.forms[0].submit(); //submits the form by script, needs a "return false" below...
document.images['wait'].src = document.images['wait'].src; //starts the stopped animation (produced by the click i guess?)
return false;
}
//-->

in the <body> part, it is needed an onsubmit event on the form like this..

<FORM onsubmit="return doSubmit()">
... form controls ...
<INPUT type=submit>
</FORM>

and the gif image should have a name (animation triggered on doSubmit function) ...

<img src="wait.gif" border=0 alt="" hspace=50 width=90 height=20 name="wait">

With this approach it functions well with "input buttons" as well.

Saludos!
# September 5, 2004 8:03 AM

Mo said:

Hmm, i ran into the same problem and i figured out a way to get it working using just a animated gif. On page unload/form submit, add -
window.setTimeout("StartAnimation()", 100)
function StartAnimation()
{
window.status ="Getting Results...Please Wait...";
document.images.item(0).src = "images/wait.gif;
}

That worked for me!
# September 27, 2004 9:27 AM

Amit Saha said:

hi All,

I have tried the solutions and it works fine with IE 6.0 but it's not working in IE 5.0 and Netscape 4.7
# December 16, 2004 11:35 PM

sdfg said:

sdfg
# December 23, 2004 10:34 AM

John said:

Man oh man.... I started to think, gee, maybe there is a really cool way to break IE and get this to work....

I'm just going to borrow your SWF (Yoink!) and go that route!

Who'd have thought this could cause so much trouble!
# December 28, 2004 8:00 AM

gk said:

i had gone with the hiding and showing gif route, but was ready to declare it impossible after another scan of the web for answers.

resetting the img.src worked for me, and sure beat all the apache output flushing i thought i'd have to do (made uglier by needing to disable mod_gzip).
# January 5, 2005 4:12 AM

Rama Krishna said:

Hi ,
I have a problem with displaying progress bar when the user submits a request. actually i am using onbeforeunload event in javascript and iterating an image it is working fine, but the problem is while the user subnits the form and the request is being processed if the user clicks stop button in the browser the animation is not stopping can any one suggest me a solution for this. so that when a user wants to cancel a request even the progressing bar animation will stop. thanks in advance.

Bye
Rama Krishna.
iamvemuri@yahoo.com
# January 10, 2005 5:53 PM

diwan said:

Hi Brendan Tompkins, could you give me the flash? loading.swf? my email is at di_wan@163.com Thank
# January 15, 2005 8:47 AM

Todd Hinton said:

Hi Brendan. Great article. Just what I was looking for.

Could you send me loading.swf? My email is thinton@resource-one.us. Also, if you have a sample .net app that does that would be helpful as well.

Thanks!

Todd
# February 1, 2005 2:50 PM

Vladimir Georgiev said:

Maybe you should all set your Tools -> Internet Options -> Advanced -> Play Animations in web pages to TRUE before testing...

It saved me a lot of time.

(PS: I use Windows 2003 Enterprise, which makes this feature disabled by default).
# February 9, 2005 2:06 AM

TrackBack said:

# March 1, 2005 1:50 PM

TrackBack said:

# March 1, 2005 1:52 PM

David said:

Nobody has considered if the form is runat="server"

The problem with changing the onsubmit="formSubmit()" of a form, means the form doesn't actually submit properly.

Any solution to this common scenario?
# July 6, 2005 8:24 AM

Aaron said:

Here's my solution:

1.) put a div tag where you want your progress bar (in this case, we're faking it with an animated gif) to show up on the page and give it an id:

"<div id="waitImg"></div>"


2.) if you're using asp.net, hide the button put there by the code and create a regular html button. Put a function call into the OnClick of the button:

hidden asp.net button: "<asp:Button id="btnSubmit" runat="server" CssClass="BUTTON_HIDDEN" Visible="true">"

html button to show instead: "<input type=button id="btnHideSubmit" name="btnHideSubmit" value =" Submit " class="button" onclick="doClick('btnSubmit');" runat=Server>"

4.) in the javascript for the OnClick, set the div's innerHTML to a borderless, marginless, nonscrolling iframe that contains a link to a small html file with your progress bar. Also, find the asp.net button and do a [button_id].click. I use getElementByID so I can pass in any button name and reuse the code:


function doClick(btn)
{
var i = document.getElementById("waitImg"); // find the div tag
setTimeout("submitButtonClick('" + btn + "')", 75); // click the button
i.innerHTML = "<iframe width='100' height='20' frameborder='0' scrolling='no' marginwidth='0' marginheight='0' src='progressbar.html'></iframe>"; // show the iframe
}


function submitButtonClick(btn){
var o = document.getElementById(btn);
o.click();
}

Now, here's the trick part -- in my code, the first thing that runs in the event handler (after calling a function that takes some time to run) is a thread.sleep. Thus the page won't refresh until it posts back to the browser. How, then, to force the image in the iframe to loop? I found that all you have to do is refresh the html page in the Iframe once after the button is clicked and the animation will reload and play while the page is waiting for the response from the server. Here's the javascript I put in the head tag in the progressbar.html page:

function reloadOnce(){
myvar = location.search.substr(1);
if (myvar=="b"){
}else{
setTimeout("location.href=location.href+'?b'",150);
}}
window.onload=checkit;

This is a snippet of javascript I found randomly on the internet -- I had be using meta-refresh, but I only wanted the page to reload once.

Notice that I have a bit of a wait -- 75 milliseconds -- between the html button being clicked and the hidden submit button being clicked. I have a corresponding wait of 150 milliseconds in the javascript that reloads the progressbar.html page. These aren't necessary, but I suggest a bit of a wait in the progressbar.htm page just to be sure that the calling page has already started submitting. So, while the main page can't refresh because it's in the process of submitting the form, the iframe refreshes and reloads the animation, thus getting around the annoying behaviour in IE where animated gifs stop looping between clicking on a submit button and getting a response.

One could, with a bit of work, make this less static -- if the progressbar.html page were an asp or aspx page, you could use meta-refresh to refresh at a predetermined interval and run some code on the page to check on your process asynchronously.

Hope this is useful -- heaven knows I spent too much time trying to figure out how to do this without using out-of-band calls to the xmlhttp object...
# July 29, 2005 2:08 PM

Jay said:

Thanks Christian Salazar -- that worked.
# December 27, 2005 12:16 PM

Ricardo said:

Guys simply get the gif and use innerHTML into the div, then calls a function with timeout to "re-do" de innerHTML function.

function carregando() {
//document.getElementById("loading").style.visibility = "visible";

var carregador = new Array();
carregador[0] = "<h1>Aguarde...</h1>";
carregador[1] = "<img src=\"../../img/carregando.gif\" alt=\"Aguarde, carregando...\" />";

document.getElementById("loading").style.visibility = "visible";  

document.getElementById("loading").innerHTML = carregador.join("\n");
}

function recarregando() { window.setTimeout("carregando()", 500); }
# June 6, 2006 4:31 PM

Garth said:

I found the javascript setTimeout trick works quite well.  In my scenario (ASP.NET 2 w/C#), I have an asp:Button (with submit behaviour) with an OnClientClick handler that runs a javascript function.  This function shows a hidden div with the loading image, then sets a timeout for 100ms to then run another function which reloads the image's src.
----------------
   var tO;
   function Progress(btn) {
       //btn is the button which was just clicked.
       //qT is the div which contains arbitrary text which I want to hide
       var qT = document.getElementById("summary");
       //p is the div that contains the progress bar image.
       var p = document.getElementById("progress");
       
       //prevents the user from clicking the button again.
       btn.onclick = function() {
           return false;
       }

       qT.style.display = "none";
       p.style.display = "block";

       tO = setTimeout("ProgressBar()", 100);
       
       return true;
   }

   function ProgressBar() {
       clearTimeout(tO);
       var pI = document.getElementById("pI");
       pI.src = "images/loading.gif";
   }
----------------

whew!
# June 14, 2006 9:56 PM

Moxley Stratton said:

"IE stops animating gif images when a form is submitted" (note: Mozilla doesn't have this problem)

"My life has been much easier since I stopped caring about the nerds who use mozilla"

Sure, I believe that. ;)
# June 15, 2006 11:39 AM

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News

MVP
Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.