To read the article online, visit http://www.4GuysFromRolla.com/articles/033110-1.aspx

Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Refreshing An UpdatePanel With JavaScript

By Scott Mitchell


Introduction


The ASP.NET AJAX UpdatePanel provides a quick and easy way to implement a snappier, AJAX-based user interface in an ASP.NET WebForm. In a nutshell, UpdatePanels allow page developers to refresh selected parts of the page (instead of refreshing the entire page). Typically, an UpdatePanel contains user interface elements that would normally trigger a full page postback - controls like Buttons or DropDownLists that have their AutoPostBack property set to True. Such controls, when placed inside an UpdatePanel, cause a partial page postback to occur. On a partial page postback only the contents of the UpdatePanel are refreshed, avoiding the "flash" of having the entire page reloaded. (For a more in-depth look at the UpdatePanel control, refer back to the Using the UpdatePanel installment in this article series.)

Triggering a partial page postback refreshes the contents within an UpdatePanel, but what if you want to refresh an UpdatePanel's contents via JavaScript? Ideally, the UpdatePanel would have a client-side function named something like Refresh that could be called from script to perform a partial page postback and refresh the UpdatePanel. Unfortunately, no such function exists. Instead, you have to write script that triggers a partial page postback for the UpdatePanel you want to refresh. This article looks at how to accomplish this using just a single line of markup/script and includes a working demo you can download and try out for yourself. Read on to learn more!

Different Ways To Refresh an UpdatePanel via JavaScript


In order to refresh an UpdatePanel control via script we need to trigger a partial page postback for that UpdatePanel. As discussed in previous articles, any control within an UpdatePanel that would normally trigger a postback when clicked will trigger a partial page postback. For example, a Button Web control placed within an UpdatePanel will cause a partial page postback when clicked. It's also possible to have Web controls outside of the UpdatePanel trigger a partial page postback. This is accomplished by specifying that the Web control of interest is an AsyncPostbackTrigger for the UpdatePanel.

Refreshing an UpdatePanel from client-side script requires that we trigger a partial page postback. One way to accomplish this is to perform the following steps:

  1. Add a Button Web control to the page,
  2. Configure the Button to cause a partial page postback for the UpdatePanel in question (either by placing it within the UpdatePanel or by putting it outside of the UpdatePanel, but making it an AsyncPostbackTrigger for the UpdatePanel),
  3. Use CSS to hide the button so that the end user does not see it, and
  4. Write JavaScript that "clicks" the button.
If you follow the above steps you can then refresh the UpdatePanel by running the JavaScript code created in step 4.

While the above steps certainly work, having to add a hidden Button control seems like a bit of a hack. The good news is that there is a simpler and cleaner approach to triggering a partial page postback. The ClientScriptManager class contains a method called GetPostBackEventReference that generates client-side script that triggers a postback. You can use this method to generate the script to cause a postback triggered by the UpdatePanel itself. Because its the UpdatePanel that triggers the postback a partial page postback is used instead.

This article (and the demo available for download at the end of this article) focus on this latter approach. For more information on refreshing an UpdatePanel via JavaScript by "clicking" a hidden Button, see Jeffrey Zhao's blog entry, Refresh the UpdatePanel using JavaScript Code. Also see Joe Stagner's video, [How Do I:] Use JavaScript to Refresh an ASP.NET AJAX UpdatePanel, which shows both the hidden Button method and an approach similar to the one we'll explore in this article.

A Simple Demo...


Let's start by examining a very simple demo for refreshing the content in an UpdatePanel using client-side script. (The demos examined in this article are available for download at the end of this article.) This simple demo contains two Label controls whose Text property is set to the current date and time in the Page_Load event handler. One of the Labels, lblCurrentTimeUpdatePanel, is in an UpdatePanel. The following markup shows the UpdatePanel and the two Label controls.

<h3>NOT In An UpdatePanel...</h3>
<p>
   The current time is:
   <asp:Label ID="lblCurrentTime" runat="server"></asp:Label>
</p>

<asp:UpdatePanel ID="upCurrentTime" runat="server">
   <ContentTemplate>
      <h3>In An UpdatePanel...</h3>
      <p>
         The current time is:
         <asp:Label ID="lblCurrentTimeUpdatePanel" runat="server"></asp:Label>
      </p>
   </ContentTemplate>
</asp:UpdatePanel>

Whenever there's a partial page postback the Page_Load event handler will execute and both Labels' Text properties will be updated to the current date and time. However, a partial page postback will only update the display in the UpdatePanel, meaning that while the lblCurrentTimeUpdatePanel Label will be updated to reflect the current date and time, lblCurrentTime will continue to show the date and time when the page was first loaded (or at the last full page postback).

The demo, as it stands now, doesn't offer any way for the user visiting the page to trigger a partial page postback. We could add a Button Web control to the UpdatePanel. By virtue of being in the UpdatePanel the Button, when clicked, would cause a partial page postback. But the focus of this article is to show how to refresh an UpdatePanel from script. Instead, let's create an HTML element outside of the UpdatePanel that, when moused over, will refresh the UpdatePanel's content.

The demo includes the following markup beneath the UpdatePanel:

<div onmouseover="..." class="box">
   Move your mouse over me to update the time in the UpdatePanel!
</div>

When the visitor moves her mouse over the text the client-side onmouseover event fires and the JavaScript we place in the <div> element's onmouseover will execute. What we want to do is add script that will refresh the UpdatePanel. This is where the ClientScriptManager class's GetPostBackEventReference comes into play. This method accepts as input the control that is to trigger the postback along with any postback arguments and then returns the JavaScript that will trigger the postback. Here's how we use it:

<div onmouseover="<%=ClientScript.GetPostBackEventReference(upCurrentTime, "")%>" class="box">
   Move your mouse over me to update the time in the UpdatePanel!
</div>

The tags <%= ... %> outputs the value returned by the server-side code within the tags. Inside those tags we use the Page object's ClientScript property, which is an object of type ClientScriptManager. We call its GetPostBackEventReference method passing in the reference to the UpdatePanel that we want to refresh and an empty string for the postback arguments (since none are needed). The GetPostBackEventReference method returns the following JavaScript:

__doPostBack('UpdatePanelClientID','')

Putting it all together, with the above code in place the following markup gets sent down to the browser:

<div onmouseover="__doPostBack('ctl00$ContentPlaceHolder1$upCurrentTime','')" class="box">
   Move your mouse over me to update the time in the UpdatePanel!
</div>

And that's all there is to it! When the user mouses over the <div> element the __doPostBack JavaScript method is executed, indicating that the UpdatePanel upCurrentTime has triggered a postback. Because this postback originated from the UpdatePanel it is translated into a partial page postback. On the partial page postback the entire page life cycle is repeated, which includes the Page_Load event handler re-running and updating the Labels' Text properties to the current date and time.

The following screen shots demonstrate this behavior. The first screen shot shows the page when it is first visited.

The demo, when first loaded. Note that the times in both Labels are the same.

This screen shot, taken about 30 seconds later, shows the display after the user has moused over the <div> element. Doing so causes a partial page postback, which updates the time displayed in the second Label (lblCurrentTimeUpdatePanel).

The demo, after the user has moused over the text in the bottom right. Note that the Label in the UpdatePanel has been updated to show the current date and time.

Getting Fancy: Refreshing an UpdatePanel When Closing FancyBox


Recently, I was working on a project that contained a number of data entry pages where workers could review and edit incident reports. An incident report consisted of 20 questions which had sometimes lengthy free form answers. We wanted to provide users with the ability to read through the incident report and then easily and quickly edit the answer to a particular question. Previously, this page used a standard pre-Ajax approach - it would display each of the 20 questions and their answers with an "Edit Answer" link. Clicking that link would whisk the user to a new page where they could edit the answer. After saving the answer they'd be sent back to the review page, which would now show the updated answer text.

We decided to spruce up this page using Ajax. We started by adding 20 UpdatePanels to the page- one UpdatePanel around each question's answer. We then changed the "Edit Answer" link semantics. Instead of whisking the user to a different page we used FancyBox to display a floating window with a user interface for editing the answer to that question. (A few weeks ago I wrote an article - Displaying Multimedia Content In A Floating Window Using FancyBox - that examined FancyBox, a free client-side library that makes it easy to display text, images, and other content in a floating window.) After making their edits, the user would click the Save button in the FancyBox window, which would close the window and execute script to refresh the UpdatePanel so that it would show the updated answer text.

The net result was a user interface that was much snappier. Users reviewing these incident reports could stay on the same page when reading and editing answers. By keeping the user on the same page and by using UpdatePanels for the answer text the pages loaded faster. All in all, a very noticeable improvement that our users have been very receptive to.

The download at the end of this article includes a watered down version of this user interface. Specifically, the FancyDemo.aspx page contains just a single UpdatePanel and instead of using a database to store the answer text it is instead maintained in a session variable. Also, in this demo the visitor is editing their user profile (namely, their bio information) rather than an incident report answer .Regardless, the concept is the same and the demo could certainly be extended to a more real world scenario.

Let's look at how this demo works. The FancyDemo.aspx page contains the following markup and script:

<script type="text/javascript">
   $(document).ready(function() {
      $("#showEditBioUI").fancybox({
         'width': 550,
         'height': 250,
         'showCloseButton': false,
         'onClosed': function() {
            <%=ClientScript.GetPostBackEventReference(upBioContent, "")%>
         }
      });
   });
</script>

<b>Your Bio:</b>
[<a id="showEditBioUI" href="EditYourBio.aspx" class="iframe">Edit Bio</a>]
<br />

<asp:UpdatePanel ID="upBioContent" runat="server" onload="upProfile_Load" UpdateMode="Conditional">
   <ContentTemplate>
      <asp:Label runat="server" ID="lblBio"></asp:Label>      
   </ContentTemplate>
</asp:UpdatePanel>

First, notice the "Edit Bio" link, which appears next to the "Your Bio" heading. This link, when clicked, displays a floating window using the FancyBox library. The JavaScript in the $(document).ready function is what wires up that link to the FancyBox library. In doing so we can specify a variety of FancyBox configuration settings, such as the height and width of the FancyBox. We can also specify script to execute when the FancyBox is closed. Here, we use the ClientScript.GetPostBackEventReference method just as we did in the simple demo to refresh the UpdatePanel's contents.

The UpdatePanel contains a Label control. Whenever the UpdatePanel's Load event fires - which occurs on the first page visit as well as on partial page postbacks - the Label is assigned the current value of the logged on user's bio. (In this demo this value comes from a session variable, but in the real world it would be read from a database or some other persistent store.) Note that the UpdatePanel's UpdateMode property has been set to Conditional. This instructs the UpdatePanel to only refresh when it is the cause of a partial page postback. (By default, all UpdatePanels on the page are refreshed on a partial page postback.) This setting is superfluous for this demo since there is only one UpdatePanel, but if you have multiple UpdatePanels on the page and only can be updated at a time then you can reduce the amount of markup that needs to be sent back from the server by using the Conditional mode. And if that doesn't make any sense, be sure to read Using the UpdatePanel, which discusses the UpdateMode property in detail.

The screen shot below shows the FancyDemo.aspx page when visited through a browser. The bio is displayed as text beneath the "Edit Bio" link.

The user can view and edit their bio from this page.

Clicking the "Edit Bio" link displays a FancyBox. The FancyBox actually displays content from another web page, EditYourBio.aspx. (The URL to this page is specified directly in the link's markup, via the href attribute.) The EditYourBio.aspx page contains an UpdatePanel itself, which includes a multi-line TextBox control and Save and Cancel Buttons. On Page_Load, the TextBox is populated with the contents of the user's bio. Clicking Save updates the bio. When either the Save or Cancel buttons are clicked, JavaScript is executed that closes the FancyBox window.

The following screen shot shows the screen after the "Edit Bio" link has been clicked. The page is grayed out and a floating window appears with an interface for editing the bio information.

The user can edit their bio from a floating window thanks to FancyBox.

When the FancyBox window closes - either by the user clicking Save or Cancel - JavaScript is executed that refreshes the UpdatePanel that contains the bio. If the user had modified the contents of his bio then the new bio text would appear once the FancyBox window closed. And there you have it - using UpdatePanels, FancyBox, and script to build a slick, interactive user interface for editing content in a Web Form and automatically refreshing the UpdatePanel to display the just-edited text.

Happy Programming!

  • By Scott Mitchell


    Attachments:


  • Download the Demo Code Used in this Article

    Further Reading


  • Using the UpdatePanel
  • Refresh the UpdatePanel using JavaScript Code
  • [How Do I:] Use JavaScript to Refresh an ASP.NET AJAX UpdatePanel? (VIDEO)
  • Easily refresh an UpdatePanel, using JavaScript
  • Displaying Multimedia Content In A Floating Window Using FancyBox
  • Article Information
    Article Title: Building Interactive User Interfaces with Microsoft ASP.NET AJAX: Refreshing An UpdatePanel With JavaScript
    Article Author: Scott Mitchell
    Published Date: March 31, 2010
    Article URL: http://www.4GuysFromRolla.com/articles/033110-1.aspx


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers