Ajax.Net Example: Using an UpdatePanelAnimationExtender to place an animated gif over a GridView

 I recently was working on an Asp.Net project that contained quite a few search pages.  These pages all followed a similar structured pattern where the user had a set of fields they could filter on by typing in values and pressing the search button.  The results were displayed in a GridView where the user could sort by clicking on column headers, export the results to excel, etc...  To help improve user experience, we placed each of the GridViews in an asp UpdatePanel so while the user refined the search (sorting, adding or removing additional filters), only the GridView would be refreshed and not the entire page.  Additionally, we wanted to add a few standard UI cues (disabling the Search button, fading out the GridView, and placing a progress indicator over the GridView) letting the user know an operation was currently in progress.

Download Code | View live demo

kick it on DotNetKicks.com

It turned out that adding these UI cues was pretty easy with the help of the UpdatePanelAnimationExtender.  Applying the first 2 cues (disabling the Search button and fading out the GridView) were really simple since there were already a couple of Animation Actions already defined specifically for these tasks.  Placing the animated gif in the center of the GridView was only slightly more difficult.  After the wrapping the GridView inside the UpdatePanel and defining the Search button as the trigger, I added the markup for the UpdateProgressAnimationExtender, specify which animations I would like and when they should run.  As you can see in the code snippet below, I am telling the extender control to run the ScriptAction, EnableAction and FadeOut actions both OnUpdating (when the panel starts the async-postback) and OnUpdated (when the panel has been refreshed).  When OnUpdating runs, the onUpdating javascript function is invoked centering the animated gif over the GridView, the btnSearch asp:Button is disabled, and the contents of the UpdatePanel are faded-out.  OnUpdated fires the animations that are responsible for reversing these actions - the btnSearch button is re-enabled, the UpdatePanel is faded back in, and the onUpdated javascript function is invoked removing the animated gif.         

<asp:UpdatePanel ID="updatePanel" runat="server">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
    </Triggers>
    <ContentTemplate>
        <asp:GridView ID="gvCustomers" runat="server" AllowPaging="true" AllowSorting="true"
            PageSize="20" DataSourceID="sqldsCustomers" Width="95%">
            <AlternatingRowStyle BackColor="aliceBlue" />
            <HeaderStyle HorizontalAlign="Left" />
        </asp:GridView>
    </ContentTemplate>
</asp:UpdatePanel>
<ajaxToolkit:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server" TargetControlID="updatePanel">
    <Animations>
        <OnUpdating>
            <Parallel duration="0">
                <%-- place the update progress div over the gridview control --%>
                <ScriptAction Script="onUpdating();" />  
                <%-- disable the search button --%>                       
                <EnableAction AnimationTarget="btnSearch" Enabled="false" />
                <%-- fade-out the GridView --%>
                <FadeOut minimumOpacity=".5" />
             </Parallel>
        </OnUpdating>
        <OnUpdated>
            <Parallel duration="0">
                <%-- fade back in the GridView --%>
                <FadeIn minimumOpacity=".5" />
                <%-- re-enable the search button --%>  
                <EnableAction AnimationTarget="btnSearch" Enabled="true" />
                <%--find the update progress div and place it over the gridview control--%>
                <ScriptAction Script="onUpdated();" /> 
            </Parallel> 
        </OnUpdated>
    </Animations>
</ajaxToolkit:UpdatePanelAnimationExtender>
<div id="updateProgressDiv" style="display: none; height: 40px; width: 40px">
    <img src="Img/dot-net-green.gif" />
</div>

Like I mentioned earlier, centering the animated gif was only slightly more work.  To accomplish this I included a fixed width div tag containing the image and set its display style to none.  Then when the OnUpdating animation fires the ScriptAction, I find the div, set the display back to visible, figure out the bounds of both the GridView and the progress div, and finally I do the math to determine when the div needs to be placed to overlay the GridView.  The onUpdated function just sets the display style of the div back to none.  Here are the functions ...

function onUpdating(){
    // get the update progress div
    var updateProgressDiv = $get('updateProgressDiv'); 
    // make it visible
    updateProgressDiv.style.display = '';

    //  get the gridview element        
    var gridView = $get('<%= this.gvCustomers.ClientID %>');
    
    // get the bounds of both the gridview and the progress div
    var gridViewBounds = Sys.UI.DomElement.getBounds(gridView);
    var updateProgressDivBounds = Sys.UI.DomElement.getBounds(updateProgressDiv);
    
    //    do the math to figure out where to position the element (the center of the gridview)
    var x = gridViewBounds.x + Math.round(gridViewBounds.width / 2) - Math.round(updateProgressDivBounds.width / 2);
    var y = gridViewBounds.y + Math.round(gridViewBounds.height / 2) - Math.round(updateProgressDivBounds.height / 2);
    
    //    set the progress element to this position
    Sys.UI.DomElement.setLocation (updateProgressDiv, x, y);        
}

function onUpdated() {
    // get the update progress div
    var updateProgressDiv = $get('updateProgressDiv'); 
    // make it invisible
    updateProgressDiv.style.display = 'none';
}

 

Here is the complete markup for the page ...

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript" language="javascript">
    
    function onUpdating(){
        // get the update progress div
        var updateProgressDiv = $get('updateProgressDiv'); 
        // make it visible
        updateProgressDiv.style.display = '';

        //  get the gridview element        
        var gridView = $get('<%= this.gvCustomers.ClientID %>');
        
        // get the bounds of both the gridview and the progress div
        var gridViewBounds = Sys.UI.DomElement.getBounds(gridView);
        var updateProgressDivBounds = Sys.UI.DomElement.getBounds(updateProgressDiv);
        
        //    do the math to figure out where to position the element (the center of the gridview)
        var x = gridViewBounds.x + Math.round(gridViewBounds.width / 2) - Math.round(updateProgressDivBounds.width / 2);
        var y = gridViewBounds.y + Math.round(gridViewBounds.height / 2) - Math.round(updateProgressDivBounds.height / 2);
        
        //    set the progress element to this position
        Sys.UI.DomElement.setLocation (updateProgressDiv, x, y);        
    }

    function onUpdated() {
        // get the update progress div
        var updateProgressDiv = $get('updateProgressDiv'); 
        // make it invisible
        updateProgressDiv.style.display = 'none';
    }
    
    </script>

</head>
<body>
    <form id="form" runat="server">
        <asp:ScriptManager ID="scriptManager" runat="server" />
        <div>
            <asp:SqlDataSource ID="sqldsCustomers" runat="server" 
                SelectCommand="select customerid, companyname, contactname, contacttitle from dbo.customers"
                SelectCommandType="Text" ConnectionString="server=mberseth;database=northwind;Trusted_Connection=yes;" />
            
            <p>
                Example of using an UpdatePanelAnimationExtender to place an animated gif over a GridView while the 
                GridView is being refreshed.
            </p>
            <br />
            <table border="0" width="95%">
                <tr>
                    <td align="center">Customer ID</td>
                    <td align="right"><asp:TextBox ID="txtCustomerID" runat="server" /></td>
                    <td align="center">Company Name</td>
                    <td align="right"><asp:TextBox ID="txtCompanyName" runat="server" /></td>
                    <td align="center">Contact Name</td>
                    <td align="right"><asp:TextBox ID="txtContactName" runat="server" /></td>
                </tr>                                
                <tr>
                    <td colspan="6" align="right"><asp:Button ID="btnSearch" runat="server" Width="75" Text="Search" OnClick="BtnSearch_Click" /></td>
                </tr>
            </table>
            <br />
            
            <asp:Label ID="lblTitle" runat="server" Text="Customers" BackColor="lightblue" Width="95%" />
            <asp:UpdatePanel ID="updatePanel" runat="server">
                <Triggers>
                    <asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
                </Triggers>
                <ContentTemplate>
                    <asp:GridView ID="gvCustomers" runat="server" AllowPaging="true" AllowSorting="true"
                        PageSize="20" DataSourceID="sqldsCustomers" Width="95%">
                        <AlternatingRowStyle BackColor="aliceBlue" />
                        <HeaderStyle HorizontalAlign="Left" />
                    </asp:GridView>
                </ContentTemplate>
            </asp:UpdatePanel>
            <ajaxToolkit:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server" TargetControlID="updatePanel">
                <Animations>
                    <OnUpdating>
                        <Parallel duration="0">
                            <%-- place the update progress div over the gridview control --%>
                            <ScriptAction Script="onUpdating();" />  
                            <%-- disable the search button --%>                       
                            <EnableAction AnimationTarget="btnSearch" Enabled="false" />
                            <%-- fade-out the GridView --%>
                            <FadeOut minimumOpacity=".5" />
                         </Parallel>
                    </OnUpdating>
                    <OnUpdated>
                        <Parallel duration="0">
                            <%-- fade back in the GridView --%>
                            <FadeIn minimumOpacity=".5" />
                            <%-- re-enable the search button --%>  
                            <EnableAction AnimationTarget="btnSearch" Enabled="true" />
                            <%--find the update progress div and place it over the gridview control--%>
                            <ScriptAction Script="onUpdated();" /> 
                        </Parallel> 
                    </OnUpdated>
                </Animations>
            </ajaxToolkit:UpdatePanelAnimationExtender>
            <div id="updateProgressDiv" style="display: none; height: 40px; width: 40px">
                <img src="Img/dot-net-green.gif" />
            </div>
        </div>
    </form>
</body>
</html>

TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/23

Listed below are links to weblogs that reference Ajax.Net Example: Using an UpdatePanelAnimationExtender to place an animated gif over a GridView:

» AJAX loading indicator like GMail from Community Blogs
Simone Chiaretta wrote a very nice post about building a Gmail-like loading indicator (that means top [Read More]

» [Reference]Ajax.Net Example: Using an UpdatePanelAnimationExtender to place an animated gif over a GridView from JerryZhao
Ajax.Net Example: Using an UpdatePanelAnimationExtender to place an animated gif over a GridView [Read More]

Comments


Posted by: gokhan on June 4, 2007 12:00 AM

very useful article..thankss..

Matt,

Very interesting demos that you have on your site. Thanks for taking the time to put them up.
I have taken your code and applied it to an page of mine, but I am having some issues with Mozilla. It works fine in IE and your Grid Example works fine in both.

For some reason with mine, it fades properly in Mozilla, but when the panel is updated it does not fade back in, it actually fades out even lighter and stays that way. When it updates again, it fades darker and then when done fades back to the almost transparent state.

Differences from your example:
Using this with MasterPages,
Using Virtual Earth on the page, but not in the update panel.

I was wondering if you have run into this issue at all in your development. Thank you for your time.

Christian

Posted by: Alexander on July 2, 2007 12:00 AM

Very cool! Very useful! Great work!

Thank you! I owe you a beer/drink/pat on the shoulder.


Bye
Alexander

Posted by: abdelmasseh on July 6, 2007 12:00 AM

thank you

Posted by: alborz on July 30, 2007 12:00 AM

Hi matt,
Your demo is very usefull.
I have a problem with my program. i have to updatePanel and two UpdatePanelAnimationExtender in the same page. but both of them executed when one of the update pannels is callbacked.
may you help me. thanks

Posted by: Mike on August 9, 2007 12:00 AM

Hi, nice demo, except Im having some problems with IE7, as well as the javascript code.

In IE7, after the UpdatePanel is refreshed, sometimes the gridview ends up being cut off, as if it cannot wrap some of the text, or dynamically resize itself. This only happens when I use the animation extender.

Another problem is that the javascript code to place the gif over the gridview doesnt seem to find the gridview properly (its always null) and therefore the gif is always at the bottom.

Any help would be appreciated.
Thanks

Posted by: Becky on August 17, 2007 12:00 AM

Hi Matt,
Great article! My grid is fading properly, the button is disabled properly...however my image is always at the bottom of the page. Is there a way I can just have it at the top left of the update panel?

Thanks!

Posted by: Toast on August 23, 2007 12:00 AM

Hi Matt,

works great, but for some reason, I cant see my image. Im wondering about the line:

Ive added an alert to the onUpdating function and this doesnt appear. Ive got AjaxControlToolkit v1.0.10123.0...

Thanks

Toast

Posted by: Chris on September 27, 2007 12:00 AM

Matt,

Cool demo. Im having problems with the animation extender in ie7. While fading the grid nack in, the contents of the grid are cut off.

Any help would be greatly appreciated.

TIA,
Chris

@Chris

Thanks for the feedback Chris. Would you mind posting the code in a comment or sending it to me at matt@mattberseth.com?

Thanks,
Matt

Posted by: Erik on October 23, 2007 12:00 AM

Hi Matt -
I have the same problem with the content in the gridview being cutoff, if the updatepanel RenderMode is set to inline. If the RenderMode is set to block, then the columns are squished together. This only happens when there is a UpdatePanelAnimationExtender on the page as well.

If you found the solution to chriss problem, could you please post back here?

Thanks!

Posted by: amir on February 1, 2008 12:00 AM

thank you thank you thank you

Posted by: Andrew Wait on February 7, 2008 12:00 AM

Nice example.. but I have question about the styles on the page...

Using IE7 the style of the text on page 1 is different to all subsequent pages.. it seems that the page LOOSES the style as set once the updatepanel comes into play and reverts to the browser default (at least with IE7) ... am I mad? Any comments/workarounds?

Matt,

Great article! Thanks for sharing... exactly what I was looking for today!

Posted by: Kapil Saraswat on April 13, 2008 12:00 AM

Hi Matt,
Its really a great article and it helps me in acheving my goals.

Thanks once again.

Posted by: Fenil Desai on April 30, 2008 12:00 AM

I m using a Master Page and in the Content PAge there is a grid view.
while using var gridView = $get();
I m not getting the grid view element.

Pls help.

Posted by: Giorgio Bozio on May 25, 2008 12:00 AM

Hi!
Great post!
If you dont want to show the gif if the grid is empty (no rows) you can modify the javascript function onUpdating() to show the div only if the grid is visible, just like this:

function onUpdating(){
// get the update progress div
var updateProgressDiv = $get(updateProgressDiv);
// get the gridview element
var gridView = $get();
var v = Sys.UI.DomElement.getVisibilityMode(gridView);
if (v)
{
// make it visible
updateProgressDiv.style.display = ;
// get the bounds of both the gridview and the progress div
var gridViewBounds = Sys.UI.DomElement.getBounds(gridView);
var updateProgressDivBounds = Sys.UI.DomElement.getBounds(updateProgressDiv);
// do the math to figure out where to position the element (the center of the gridview)
var x = gridViewBounds.x + Math.round(gridViewBounds.width / 2) - Math.round(updateProgressDivBounds.width / 2);
var y = gridViewBounds.y + Math.round(gridViewBounds.height / 2) - Math.round(updateProgressDivBounds.height / 2);
// set the progress element to this position
Sys.UI.DomElement.setLocation (updateProgressDiv, x, y);
}
}

Posted by: Ivan Draga on June 18, 2008 12:00 AM

Animation and loading data in example at all are not bound between itself, try more data and see.
Unholy english? May be.

Posted by: marcus on July 9, 2008 12:00 AM

I m using a Master Page and the Content Page had a grid view.
var gridView = $get(); is returning me NULL

Pls help.

Posted by: Ed on July 17, 2008 12:00 AM

I found a bug with the UpdatePanelAnimationExtender and I was curious if anyone else has seen this issue.

I am setting the focus of a textbox when the page loads. Everything worked fine until I added the UpdatePanelAnimationExtender to the page. I implemented it the same way as this awesome example and the functionality of the animation works great it just seems to lose focus of the textbox.

Any ideas as to why this is happening?

P.S. Matt, your blog rules. Every .net blog should be in your format(post, live demo)! You da mon!

Posted by: i have compilation error to launch it... maybe i am not good in asp.net..haiz.. on August 3, 2008 04:59 AM

i have an compilation error:
Could not load file or assembly 'System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

may anyone help me?
I really like the demo.

Posted by: Dave on August 7, 2008 12:29 PM

Is there a resolution for Chris' gridview clipping issue?

Wonder if this is a bug in the Update Panel Animation Extender as my right-most columns disappear during the fade out.

Posted by: Don on August 26, 2008 04:32 PM

Very good article.
Still need a little after the fadeIn, the font distorted.
Any ideas how to fix it?

Posted by: Martin on September 16, 2008 10:52 AM

Hi!, I have the same problem tahn Ed, any solution with the UpdatePanelAnimationExtender??.

Thanks!

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • Martin wrote: Hi!, I have the same problem tahn Ed, any solution with the UpdatePanelAnimationExtender??. Thanks!...
  • Don wrote: Very good article. Still need a little after the fadeIn, the font distorted. Any ideas how to fix it...
  • Dave wrote: Is there a resolution for Chris' gridview clipping issue? Wonder if this is a bug in the Update Pan...
  • i have compilation error to launch it... maybe i am not good in asp.net..haiz.. wrote: i have an compilation error: Could not load file or assembly 'System.Web.Extensions, Version=1.0.610...
  • Ed wrote: I found a bug with the UpdatePanelAnimationExtender and I was curious if anyone else has seen this i...
  • marcus wrote: I m using a Master Page and the Content Page had a grid view. var gridView = $get(); is returning me...
  • Ivan Draga wrote: Animation and loading data in example at all are not bound between itself, try more data and see. Un...
  • Giorgio Bozio wrote: Hi! Great post! If you dont want to show the gif if the grid is empty (no rows) you can modify the j...