Refreshing "Time Ago" Stamps Using UpdatePanel and Timer
Though the Guestbook Web form you just developed displays "time ago" stamps
as expected, it doesn't update them unless the browser window is refreshed. You can
overcome this limitation using UpdatePanel and Timer controls. To use them, first drag and drop a ScriptManager control on the Web form. Also add an
UpdatePanel control on the form. The UpdatePanel control enables partial
page rendering for your Web form. Place a Timer control inside the UpdatePanel
and set its Interval property to 5000 milliseconds. This way the UpdatePanel
will be refreshed automatically after every 5 seconds. Now, place a the DataList
control that displays the Guestbook entries inside the UpdatePanel control. You
need to databind the DataList again when UpdatePanel refreshes itself. To do
this, handle Load event of the UpdatePanel and call DataBind() method on the
DataList. The following code shows the Load event handler of UpdatePanel.
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
DataList1.DataBind();
}
If you run the Web form now, you will observe that the "time ago" stamps
automatically refresh after every 5 seconds.
Refreshing "Time Ago" Stamps Using Page Methods
The UpdatePanel and Timer approach works well, but it has its own
disadvantage. Your intention is to refresh "time ago" stamp alone but since you
have placed the DataList inside the UpdatePanel, the entire DataList will be
recreated and databound again and again with every UpdatePanel refresh.
You can avoid this overhead by updating only the "time ago" Labels and not the
entire DataList. One clever way to do this is to use AJAX to call server side
Page Method. Let's see how this can be done.
First remove the UpdatePanel and Timer control that you added to the Web form
previously (ScriptManager is still required) so that the DataList is directly
placed on the form. Next, modify the GetTimeAgo() method as shown below:
[WebMethod]
public static string GetTimeAgo(object postedOn)
{
...
}
Notice that the GetTimeAgo() method is now marked as static and is decorated
with [WebMethod] attribute. This way GetTimeAgo() becomes what is called as a
Page Method in AJAX terms. A page method is a server side method that can be
called from client side AJAX code. Page methods must be static and should have [WebMethod]
attribute. The code inside the GetTimeAgo() method remains unchanged.
Now, go to the markup (.aspx) of the DataList control and locate the Label that
displays "time ago" stamps. Modify the Label markup as shown below:
<asp:Label ID="Label8" runat="server"
Text='<%# GetTimeAgo(Eval("PostedOn")) %>'
ToolTip='<%# Eval("PostedOn") %>'></asp:Label>
Notice that earlier you only bound the Text property with GetTimeAgo()
method. Now you are also binding ToolTip property to the actual PostedOn
value. The Label control gets rendered as a <SPAN> tag and the tooltip property
gets rendered as the Title attribute of that <SPAN> tag. The following example
shows how this rendering happens:
<span id="DataList1_ctl00_Label8" title="10/27/2010 9:30:16 AM">
You need the actual PostedOn value on the client side so that you can
periodically convert it into a "time ago" stamp. Next, add a <SCRIPT> block
somewhere below the ScriptManager markup and code a JavaScript function named
GetLatestTimeAgo() as shown below:
function GetLatestTimeAgo() {
var labels = document.getElementsByTagName("span");
for (i = 0; i < labels.length; i++) {
if (labels[i].title != "") {
PageMethods.GetTimeAgo(labels[i].title, OnSuccess, OnError, labels[i].id);
}
}
}
The GetLatestTimeAgo() function first retrieves a list of <SPAN> elements
from the Web page. It then iterates through this list. If title of the <SPAN> is
set, it calls the GetTimeAgo() page method using PageMethods object. The
value of title attribute i.e. the actual PostedOn value is passed to the
GetTimeAgo() method. The OnSuccess function will be called upon successful completion
of the page method call. In case there is any error OnError function will be
called. The last parameter of the GetTimeAgo() method call is user context and you pass
the client side ID of the <SPAN> under consideration. This way OnSuccess
function will know which <SPAN> to refresh. The OnSuccess and OnError functions
are shown below:
function OnSuccess(result, userContext, methodName) {
$get(userContext).innerHTML = result;
}
function OnError(err) {
alert(err.get_message());
}
The OnSuccess function receives the "time ago" stamp as the first parameter.
The ID of the <SPAN> passed earlier is received as the second parameter. The
third parameter is the method name (GetTimeAgo in your case). Inside we simple
get hold of the <SPAN> tag matching the supplied ID and set its innerHTML
property to the latest "time ago" stamp. The OnError function simply displays
the error message if any.
Finally, handle pageLoad() event as shown below:
function pageLoad() {
window.setInterval(GetLatestTimeAgo, 5000);
}
The pageLoad() function will be called by AJAX framework when the Web page loads
in the browser.
Inside you use setInterval() method of the window object to repeatedly call
GetLatestTimeAgo() JavaScript function. The second parameter of the setInterval()
method specifies the interval in milliseconds between multiple GetLatestTimeAgo()
calls.
You can now run the Web form and see how the "time ago" stamps refresh
periodically. Notice that this time only the "time ago" Labels are refreshed and
not the entire DataList.
Note:
- In the above code you call GetTimeAgo() page method merely by checking
the title attribute. It is possible that some other <SPAN> tags outside of
DataList also have title attribute set. If so the page method call will
fail. You can put additional checks to ensure that only the <SPAN> tags
displaying the "time ago" stamps are considered while calling the page method.
- Since you already have "time ago" stamp generation logic on the server,
you used AJAX to call the server side method. You can also build a
JavaScript based version of GetTimeAgo() page method so that no server side
calls are needed.
Summary
Displaying "time ago" stamps is a popular way of displaying the time elapsed
since a post was made. In this article you learned how to generate such "time
ago" stamps. We also discussed various approaches to refreshing the "time ago"
stamps. The first approach refreshes the "time ago" stamps only after page
refresh or postback. This approach is suitable where displaying the latest
elapsed time is not critical. A simple way to automatically refresh "time ago"
stamps periodically is to use UpdatePanel and Timer controls. The downside,
however, is that the DataList is bound again and again. If you wish to avoid
this overhead you can just refresh the "time ago" Labels by making GetTimeAgo()
method as a page method and calling it from the client side AJAX code.
Related Articles
Comments
There are no comments yet. Be the first to comment!