In my AJAX patterns talk at MIX, I discussed the concept of using subtle UI effects to direct user attention to what has changed on the page in response to an action. Specifically, I demonstrated an UpdateIndicator control that used smooth scrolls and highlights to enable an application to do this, and add a nice touch of polish.
I've implemented an UpdateIndicatorPanel control within my UpdateControls suite (plus some enhancements to the existing UpdateHistory control), which is now at version 1.2 and can be downloaded along with sources and samples. Prior to this, I had an AnimatedUpdatePanel that used to animate in new content over old content during a partial post-back. That control works well when all of its contents change. The UpdateIndicatorPanel is useful when only a portion of its surrounding UpdatePanel's content has logically changed. For example, say I have a repeater within an UpdatePanel. When an item is added to the data source, the entire repeater is updated, but you're likely to want to direct the user's attention to specifically the new row as opposed to the entire set of rows. This is where UpdateIndicatorPanel comes in.
Using the Control
The included sample page uses a Repeater to display a list of data items and a FormView to add data items into the DataSource. In order to incrementally update the repeater whenever an item is added, it is within an UpdatePanel.
First, I'll add the UpdateIndicatorPanel control to the ItemTemplate, and move the original contents of the template into the panel. Don't worry, the control is a no-op in terms of IDs (i.e. nesting content does not make IDs longer), and is also a no-op in terms of rendering for all items other than the one you want to direct user attention to using a smooth scroll and an optional highlight effect following that.
<asp:Repeater runat="server" id="itemsList" DataSourceID="itemsDataSource">
<ItemTemplate>
<nStuff:UpdateIndicatorPanel runat="server" id="updateIndicator">
<!-- regular item content -->
</nStuff:UpdateIndicatorPanel>
</ItemTemplate>
</asp:Repeater>
Secondly, you'll want to call the ShowUpdate method of this control to direct the user to specific content that has been updated. In the sample, this happens everytime there is a post-back, and the last item in the Repeater is a newly inserted item.
protected override void OnPreRenderComplete(EventArgs e) {
base.OnPreRenderComplete(e);
if (!Page.IsPostBack) {
return;
}
RepeaterItem lastItem = itemsList.Items[itemsList.Items.Count - 1];
UpdateIndicator updateIndicator = (UpdateIndicator)lastItem.FindControl("updateIndicator");
updateIndicator.ShowUpdate(/* addHighlight */ true);
}
The server control exposes properties you can use to specify a CSS class for the highlight that can be used to determine the highlight color, as well as duration properties that control the timespan over which the animation is performed. Remember a tip I mentioned when introducing AnimatedUpdatePanel - find a duration that works well for demo, then half it for actual use, so you minimize the annoyance factor.
Behind the Scenes
The UpdateIndicatorPanel emits an instance of a client-side UpdateIndicator script behavior that is attached to the <div> rendered around the item content. Once the updated repeater content is displayed, the script behavior is instantiated, and during its initialization it creates a scroll effect. Once the scroll effect plays through, the behavior creates a highlight effect, and plays that if a highlight was added in addition to the basic scrolling gesture. The animation framework was pulled in from Script#, and all the client-side script was also written in Script# (I'll be releasing a Script# build soon that is targeted specifically at Microsoft ASP.NET AJAX).
Some Philosophy
Generally AJAX applications have a bad rap in that they are poor in providing feedback about what has changed. Certainly this can be a challenge. However, I see both AJAX and other rich client apps such as those written using Silverlight have the opportunity to be able to do a better job than traditional post-back-based pages, simply because the browser doesn't do its default thing. Specifically, since the entire page is not refreshed, and that leaves a sort of clean slate, where the application can do something more meaningful that is specifically tuned to the application scenario at hand.
I am interested in hearing about other mechanisms people have thought about or used to communicate how and what portions of their dynamic pages have changed, as well as other things that UpdateIndicatorPanel could offer besides scrolling and highlighting.
Posted on Wednesday, 5/16/2007 @ 12:50 PM
| #
Projects