Friday, April 30, 2010

Displaying Time Spent on Page

In order to display the time spent on the page, we will have to create an UpdatePanel that updates every second. In order for this to not affect the rest of the page, we will put other functionality in another Update Panel. To programmatically update the time, we will use an AJAX Timer control. But first, let us begin by adding a ScriptManager control to our ASPX page:


<asp:scriptmanager id="SM1" runat="server"></asp:scriptmanager>
The next thing to do is add our UpdatePanel that will display the time spent on the page:

<asp:UpdatePanel ID="UP_Timer" runat="server" RenderMode="Inline" UpdateMode="Always">
<Triggers>
</Triggers>
<ContentTemplate>
</ContentTemplate>
</asp:UpdatePanel>
Notice that we have included the triggers tag, as well as the content template. The trigger we are going to use will be an AJAX Timer control. Let's add that in now, as well as set the Trigger attributes:

<asp:UpdatePanel ID="UP_Timer" runat="server" RenderMode="Inline" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick" />

<asp:Literal ID="lit_Timer" runat="server" /><br />
<asp:HiddenField ID="hid_Ticker" runat="server" Value="0" />
</ContentTemplate>
</asp:UpdatePanel>
We add an AsyncPostBackTrigger and set the control ID and Event Name to match our Timer control. We also set the Interval of the Timer's tick event to 1000 milliseconds. We have added a Literal control to display the time spent on the page, and then a HiddenField to store that value. We add code to the code-behind that will run every second, on the Tick event of the Timer control (we can do this by simply adding the code manually, or double-clicking the timer control in Design view):

protected void Page_Load(object sender, EventArgs e)
{
if (! IsPostBack)
{
hid_Ticker.Value = new TimeSpan(0, 0, 0).ToString();
}
}

protected void Timer1_Tick(object sender, EventArgs e)
{
hid_Ticker.Value = TimeSpan.Parse(hid_Ticker.Value).Add(new TimeSpan(0, 0, 1)).ToString();
lit_Timer.Text = "Time spent on this page: " + hid_Ticker.Value.ToString();
}

First, on page load we are assigning a new value to the hidden field, of type TimeSpan. This TimeSpan is 0 hours, 0 minutes, and 0 seconds. Then on each Tick event, we add one second to that value, then display it in the Literal control. If we now run this page, we will see the page programmatically and seamlessly count up the time spent on the page.
To demonstrate that this will not interfere with other functions on the page, let's go ahead and add another Update Panel:
<form id="form1" runat="server">
<asp:ScriptManager ID="SM1" runat="server" />

<asp:UpdatePanel ID="UP_Timer" runat="server" RenderMode="Inline" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />

</Triggers>
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick" />
<asp:Literal ID="lit_Timer" runat="server" /><br />
<asp:HiddenField ID="hid_Ticker" runat="server" Value="0" />
</ContentTemplate>

</asp:UpdatePanel>

<br />

<asp:UpdatePanel ID="UP_Name" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
Add your name: <asp:TextBox ID="fld_Name" runat="server" /><br />

<br />
<asp:Button ID="btn_Submit" runat="server" Text="Submit" onclick="btn_Submit_Click" /><br />
<asp:Literal ID="lit_Name" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</form>


using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (! IsPostBack)
{
hid_Ticker.Value = new TimeSpan(0, 0, 0).ToString();
}
}

protected void Timer1_Tick(object sender, EventArgs e)
{
hid_Ticker.Value = TimeSpan.Parse(hid_Ticker.Value).Add(new TimeSpan(0, 0, 1)).ToString();
lit_Timer.Text = "Time spent on this page: " + hid_Ticker.Value.ToString();
}

protected void btn_Submit_Click(object sender, EventArgs e)
{
lit_Name.Text = "Thanks. Your name is: " + fld_Name.Text;
}
}

No comments: