Solving the ASP.NET UpdateProgress Div Problem 

Monday, November 09, 2009 9:58:00 AM
Rate this Content 0 Votes

 Introduction - What is the ASP.NET UpdateProgress Control?

The UpdateProgress control is a very handy control meant for use in conjunction with an ASP.NET UpdatePanel. The UpdatePanel is an ajax control that makes it very easy to update part of a page using an ajax postback rather than a full postback. This avoids page flicker and also leaves the page not in a postback state, that is, a subsequent refresh of the browser won't force a postback. The UpdateProgress control is desinged to make it easy to show some markup while the update is happening to give the user a visible cue that something is happening. So a typical trick is to show an animated working indicator something like this working indicator

So you would add the UpdateProgress control inside the UpdatePanel something like this:

<asp:Button ID="btnSavePreferences" runat="server" />
<asp:UpdateProgress ID="progress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<img src='<%= Page.ResolveUrl("~/Data/SiteImages/indicators/indicator1.gif") %>' alt=' ' />
</ProgressTemplate>
</asp:UpdateProgress>

The Problem - Block Rendering instead of Inline Rendering

The problem is that the UpdateProgress control renders as a div element which is a block element rather than an inline element, so instead of rendering the indicator right next to your button, it renders it below your button on a new line. In some cases that may be ok, but if you really want the indicator to just be right next to the button it's a problem. I came across this situation recently in my work on mojoPortal and I really wanted to show the indicator in the same line as the button, it gave a bad effect for the indicator to jump below the button. So I did some searching on the internet and found a number of people complaining about this problem and a few less than satisfactory suggestions for solving it.

So, in summary, the problem is that it renders as a div which is a block element and the javascript associated with the control changes from display:none; to display:block when the UpdatePanel is updating.

The Solution- Borrow The UpdateProgress control from the Mono Project and modify it.

What I really wanted was to make the UpdateProgress control render as a span which is an inline element and I wanted the javascript to toggle between display:none; and display:inline;. Often, when I face a situation where an ASP.NET control cannot be coerced into rendering or behaving as I would like, I have found that I can borrow the Mono Project implementation of the ASP.NET control and modify it to meet my needs. Sometimes its more difficult than others to use this approach depending on what mono internals it may be using, but in this case it was fairly easy.

First I grabbed the UpdateProgress.cs from the Mono source code and added it to my project as UpdateProgressSpan.cs and changed the namespace to match my own project. Then it was fairly simple to change the rendering to use a span instead of a div. However, the problem still remained that the javascript would set the display to block which would still make the span render as a block just like a div. So I scrounged around in the javascript for ms ajax and found the relevant part for UpdateProgress. I copied it into my own javascript file, changed the namespace, and modified it to use display:inline instead of display:block.

The only changes I had to make in my UpdateProgressSpan.cs were:

1. In OnPreRender I had to tell it about my javascript like this:

ScriptReference SRef = new ScriptReference();
SRef.Path = "~/ClientScript/ajaxupdateprogressspan.js";
ScriptManager.Scripts.Add(SRef);
ScriptManager.RegisterScriptControl(this);

2. In Render, I changed it to use Span instead of div and use inline instead of block.

3. In the GetScriptDescriptors method I changed it from referencing the original ms ajax to use my custom one like this:

ScriptControlDescriptor descriptor = new ScriptControlDescriptor("mojo._UpdateProgress", this.ClientID);

Finally in my page I used my custom control instead of te ASP.NET version like this:

<asp:Button ID="btnSavePreferences" runat="server" />
<portal:UpdateProgressSpan ID="UpdateProgress2" runat="server" AssociatedUpdatePanelID="UpdatePanel1" >
<ProgressTemplate>
<img src='<%= Page.ResolveUrl("~/Data/SiteImages/indicators/indicator1.gif") %>' alt=' ' />
</ProgressTemplate>
</portal:UpdateProgressSpan>

Problem solved, the working indicator displays right next to the button.

If you would like to use this in your project, feel free, here is a .zip with the files.

Share This Using Popular Bookmarking Services
Copyright 2003-2010 Joe Audette

re: Solving the ASP.NET UpdateProgress Div Problem

Monday, November 09, 2009 6:00:36 PM Sandro

Just apply "float:right" to the UpdateProgress control, and make sure UpdateProgress and whatever other control are properly scoped to a block whose width you can control.


re: Solving the ASP.NET UpdateProgress Div Problem

Tuesday, November 10, 2009 6:32:50 AM Stifu

"Also, the !Important is not used by IE 6 unless in standards compliant mode which is not the default and not commonly used in IE 6."
Actually, IE6 doesn't support !important at all. IE7 in strict mode does.

Also, rather than reusing the Mono control (which is a bit extreme), couldn't you change the HTML code generated by the UpdateProgress? It's possible to change the code any control generates (as described here: http://www.asp.net/CssAdapters/).

PS: I had to use IE to post this, your comment field doesn't display in Firefox...


re: Solving the ASP.NET UpdateProgress Div Problem

Tuesday, November 10, 2009 7:34:45 AM Joe Audette

 Hi Sandro,

The problem with the float right approach is I don't know how wide the scoped container needs to be because the button can be localized and will adapt to the length of the text. It would be difficult to get it in a consistent position in relation to the button.

Best,

Joe


re: Solving the ASP.NET UpdateProgress Div Problem

Tuesday, November 10, 2009 7:40:58 AM Joe Audette

 Hi Stifu,

Implementing a custom control adapter may have been another possible approach to this problem, but to me borrowing from Mono in this case was easy, nothing extreme about it, the control is not very complex to begin with and only needed very minor modifications to get the result I wanted. To me this was the easy way. Implementing a custom control adapter would have been more work, and would have depended on the .browser file settings and browser detection.

Sorry about the editor problem I will fix that today, this site has not been upgraded in a while 

Best,

Joe


re: Solving the ASP.NET UpdateProgress Div Problem

Tuesday, November 10, 2009 9:36:51 AM Lionel

I agree with Stifu. I am glad that your approach worked for you, but Stifu's suggestion is a much, much better solution in general for everyone else. Rather the re-invent a wheel and subsequently own that wheel in terms of maintenance and support, you simply change the behavior of the control on the fly for your own needs. This kind of change would simply not require you to detect the browser, as you are merely transforming the proper div into a span -- this is trivial. What you did was pretty extreme, alright. But again, I am glad that your approach worked for you.


re: Solving the ASP.NET UpdateProgress Div Problem

Saturday, January 16, 2010 7:54:13 AM Joe Audette

Hi Lionel,

I would have liked it better to implement this as a control adapter. However I was not sure how or if it is possible to override the javascript in the base control using a control adapter.

See, the solution requires more than just changing the div to a span, the javascript must also be changed because the built in javascript is setting display:block; which will make a span behave just like a div, so it is not sufficient to just change to a span to solve this problem.

Best,

Joe


Comments are closed on this post.
Donate Money to support the mojoPortal Project. View Joe Audette's profile on LinkedIn View Joe Audette's profile on The Guild of Accessible Web Designers site