Update Panel with Animation I noticed that a lot of people found my mouse pointer as AJAX progress indicator example by using search terms suggesting they were looking for a more graphical indicator. So, here’s an example of doing something more… Web 2.0.

Like last time, I’ll base it on a standard UpdatePanel demo using a button control to set a time/date label, with an artificial delay:

<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div id="Container" class="Normal">
  <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
      <asp:Label ID="Label1" runat="server" Text="Update Me" />
      <asp:Button ID="Button1" runat="server" 
        OnClick="Button1_Click" Text="Button" />
    </ContentTemplate>
  </asp:UpdatePanel>
</div>
protected void Button1_Click(object sender, EventArgs e)
{
  Thread.Sleep(5000);
 
  Label1.Text = DateTime.Now.ToString();
}

I’ll style the container div with CSS to add a simple border and set up a class for the progress state:

.Normal
{
  border: dashed 1px #000000;
  background-color: #FFFFFF;
  cursor: auto;
  padding: 10px;
  width: 200px;
  text-align: center;
}
 
.Progress
{
  border: dashed 1px #000000;
  background-color: #EEEEEE;
  background-image: url(spinner.gif);
  background-position: center center;
  background-repeat: no-repeat;
  cursor: wait;
  padding: 10px;
  width: 200px;
  text-align: center;
}

Finally, hook up our event handlers for BeginRequest and EndRequest:

<script language="javascript">
  // Get a reference to the PageRequestManager.
  var prm = Sys.WebForms.PageRequestManager.getInstance();
 
  // Using that prm reference, hook _initializeRequest
  // and _endRequest, to run our code at the begin and end
  // of any async postbacks that occur.
  prm.add_initializeRequest(InitializeRequest);
  prm.add_endRequest(EndRequest);
 
  // Executed anytime an async postback occurs.
  function InitializeRequest(sender, args) 
  {
    // Change the Container div's CSS class to .Progress.
    $get('Container').className = 'Progress';
 
    // Get a reference to the element that raised the postback,
    //   and disables it.
    $get(args._postBackElement.id).disabled = true;
  }
 
  // Executed when the async postback completes.
  function EndRequest(sender, args) 
  {
    // Change the Container div's class back to .Normal.
    $get('Container').className = 'Normal';
 
    // Get a reference to the element that raised the postback
    //   which is completing, and enable it.
    $get(sender._postBackSettings.sourceElement.id).disabled = false;
  }
</script>

The end result isn’t too shabby at all: