Skip navigation.

Disabling Page Transitions in Internet ExplorerAll recent postsImpressive Event Library from Yahoo!

Displaying Progress Indicator During Callbacks

When designing web user interfaces with callbacks (aka “Ajax”), it’s important to provide visual cues that something is happening and advise the user to wait a second or two. People regard Google Suggest as the ultimate “Ajax” application. Google Suggest works lightening fast because they can afford fast hardware, and are able to search through their giant storage and deliver suggestions in under a second. For most of us it’s an unattainable dream, and we have to deal with very real latencies.

Under these circumstances users may get easily confused when, for example, they click a button but see no traditional browser response, such as a page postback or refresh. I think this aspect of “Ajaxy” applications gets overlooked very often. Ideally, you need to display a progress indicator before a callback is placed and hide it as upon response completion. The progress indicator I allude to may be simply an animated image like the famed MacOS spinning pizza of death.

For example, if you use the Telerik suite of callback controls, you display a progress indicator upon onRequestStart, and remove it on onReponseEnd:

<script type="text/javascript">
function onRequestStart() { ProgressIndicator.display(); }
function onResponseEnd() { ProgressIndicator.hide(); }
</script>

<radclb:CallbackButton id="TestButton" runat="server"
   Text="(Your text goes here)" 
   DisableAtCallback="true"
   AllowOtherCallbacks="false"
   ClientEvents-OnRequestStart="onRequestStart"
   ClientEvents-OnResponseEnd="onResponseEnd" />

ProgressIndicator is designed as a JavaScript singleton class with two public methods: display(anchorId) and hide(). You pass to display the id of an arbitrary element and it displays a progress indicator image on top of this element during callback.

For example, I developed a sample with four test cases. The sample imitates an “Ajax” callback by simply setting a timer. In the real world you’ll have an actual request/response sequence here.

My rule of thumb is to display a progress indicator on top of the calling control. I think it sends a clear message to the user that the action is being performed in response to the clicked control. This is exactly what happens when you click the check box, both buttons, or select a list item.

Since we use Telerik controls, I used their animated GIFs as visual cues. Depending on the dimensions of the covered element, ProgressIndicator picks an image of appropriate size. This is why you see a bar when you click Run test 1—it simply is not high enough to accommodate the larger image.

I’d like to also point out that if no anchorId is passed to the display method, the progress area is centered in the middle of the browser window. Click Run test 3 to see how it works.

Implementation Details

I liked Nikhil’s way of declaring private class members and accompanying “property setters” and “getters.” ProgressIndicator has two private instance variables, _anchorId and _inProgress, each with a pair of private getters and setters. Both display and hide are privileged methods and therefore can access private methods. See Private Members in JavaScript by Douglas Crockford to learn more about this.

Conclusion

The sample is a close-enough approximation of what we use in production, while the ProgressIndicator class itself is fully functional. Please note that in the sample you can kick off several tests at the same time. ProgressIndicator won’t allow re-entrancy while a callback is in progress, but the use of setTimeout in the sample produces a funky effect.

In a real-world scenario you need to decide whether you allow simultaneous callbacks or require them placed sequentially. For example, Telerik controls have a handy property, AllowOtherCallbacks, to configure this behavior. Personally, I prefer sequential callbacks.

I tested the sample in Mozilla, Opera, IE/Win 5.0, 5.5, 6.0. If you have any comments or suggestions, please speak up.

Comments

Comment permalink 1 TimT |
Great example, thanks for posting it. I have extracted what I needed and applied it to my project, but I am short on the call back code.

What I have is report.aspx. The user enters criteria, hits the submit button and report.aspx then re-renders itself per the criteria. During this period I'd like to show a progress spinner.

Could you expand on the comments within DisplayProgress()?
" In real life you'd be initiating a callback here and calling ProgressIndicator.hide() when the response comes back. "

Thanks!
Tim T.
Comment permalink 2 Milan Negovan |
Sure, Tim. I would expect an Ajax widget to initiate a callback from JavaScript and signal when it receives a response.

For example, the Telerik control we use has two client-side events: OnRequestStart and OnResponseEnd, which call the display() and hide() functions respectively.
Comment permalink 3 TimT |
Thanks for the quick reply! Your guidance helped me get this item wrapped up.

Emails and Notifications

Would you like to be notified when somebody responds to this post?  Would you like to have these comments emailed to you?

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):