Using the UpdatePanel UpdateProgress and Timer Controls
For this first example, consider the following scenario: You have a data-driven web page that needs to continuously alert the user with fast changing data, for instance, a page that displays the major financial indices in the U.S. capital markets: Dow Jones Industrial Average (DJIA), NASDAQ, and S&P500. One approach is to place a <META> tag in your page with refresh values that then force the page to refresh itself in regular intervals based on the provided value. But if you wanted to make the page behave more like a desktop application and update the data without page refresh, AJAX is definitely the recommended path.
By now, you have seen the basics of the ScriptManager, UpdatePanel, UpdateProgress, and the Timer server controls in ASP.NET AJAX and have a good understanding of their functionality. So, with that in mind, let's build a quick application that does exactly what was talked about earlier: displays the three main indices of the American capital markets and continues to update the page with (simulated) real-time data without any page refresh.
To accomplish this, create a new ASP.NET AJAX-enabled web site. Because the ScriptManager control has already been placed on the page, drop new UpdatePanel, UpdateProgress, and Timer controls onto the page called MarketData.aspx as shown in Figure 6-1.
Figure 6-1. New page with ASP.NET AJAX server controls
After that, you just need an HTML table and a few label controls for the user interface. Let's take a look at the actual markup for this page:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="MarketData.aspx.cs" ^ Inherits="MarketData" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ^ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server">
<title>Market Summary</title> </head> <body>
form id="form1" runat="server"> <div>
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> </div>
<u>Market Summary:</u> <br /><br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server"> <Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers> <ContentTemplate> <table border="1"> <tr>
<td><asp:Label ID="Label1" runat="server" Text="DJIA"></asp:Label> </td>
<td align=right><asp:Label ID="lblDowJones" runat="server" Text="12000"></asp:Label></td> </tr> <tr>
<td><asp:Label ID="Label2" runat="server" Text="NASDAQ"></asp:Label> </td>
<td align=right><asp:Label ID="lblNasdaq" runat="server" Text="2500"></asp:Label></td> </tr> <tr>
<td><asp:Label ID="Label3" runat="server" Text="S&P 500"> </asp:Label></td>
<td align=right><asp:Label ID="lblSnp" runat="server" Text="1400"> </asp:Label></td> </tr> </table> </ContentTemplate> </asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>Updating...</ProgressTemplate> </asp:UpdateProgress> <asp:Timer ID="Timer1" runat="server" Interval="2000" OnTick="Timer1_Tick" />
By now, you are probably familiar with most of this code. Basically, we are using an <asp:AsyncPostBackTrigger> trigger in the main UpdatePanel control and associating it with the Tick event of the Timer control. To better show the updates taking place, you use an UpdateProgress control with the text "Updating..." in its <ProgressTemplate> tag. In the Timer control, you set the interval to 2 seconds (2000 milliseconds) and point the OnTick event to the Timer1_Tick event handler in the code behind, which will be responsible for writing the logic to fetch and display the new values for the three indices.
Obviously, the point of this application is to showcase a good scenario for using ASP.NET AJAX server controls and not to build a practical market data reporting application. As such, the initial values for the three indices have been hard-coded in the tags themselves. The initial value for the DJIA is set to 12000, the NASDAQ is set to 2500, and the S&P is set to 1400. There will also be some simple logic to update the display values of those indices with some fictitious data as shown in the following code block in the code-behind class:
protected void Timer1_Tick(object sender, EventArgs e)
System.Threading.Thread.Sleep(l000);
lblDowJones.Text = ((int.Parse(lblDowJones.Text)) + l).ToString(); lblNasdaq.Text = ((float.Parse(lblNasdaq.Text)) + 0.5).ToString(); lblSnp.Text = ((float.Parse(lblSnp.Text)) + 0.25).ToString();
First, you initiate a one-second delay by pausing the current thread, and then you increment the values of each label control by holding the value for the market indices and assigning them back to the corresponding labels. As you can see, the value for DJIA is incremented by one point, the NASDAQ index is incremented by a half point, and the S&P 500 index is incremented by a quarter point. This update effectively takes place every three seconds because the Timerl_Tick event is called every two seconds followed by a one-second delay in the method.
Figure 6-2 shows MarketData.aspx in the browser during an update.
|
Market Summary - Windows Internet Explorer US! ia^ | ||
|
- htW/localhost/ajaxcl v| *t X | ||
|
ik & | ||
|
Market Sumnnarv |
& ' | |
|
|pjlA |
12006 |
|
NASDAQ |
2503 |
|
S&P 500 |
Lpdating... Figure 6-2. MarketData.aspx updates the values for the indices every three seconds. As you can see, the index values in the page change every two seconds (with a one-second pause between updates and one second after the update without any refresh at all). If you were to refresh the page, you would notice all three values being reset to their initial values that were set in the page designer. Now view the source in the browser, and notice the generated client code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ^ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head><title> Market Summary </title></head> <body> <form name="form1" method="post" action="marketdata.aspx" id="form1"> <div> <input type="hidden" name="_EVENTTARGET" id="_EVENTTARGET" value="" /> <input type="hidden" name="_EVENTARGUMENT" id="_EVENTARGUMENT" value="" /> <input type="hidden" name="_VIEWSTATE" id="_VIEWSTATE" value="/wEPDwULLTE0NDcxODQxOTNkZBVyy3kZPCaHntKg63oJ/pIvM3rf" /> </div> <script type="text/javascript"> <!-- var theForm = document.forms['form1']; if (!theForm) { theForm = document.form1; function _doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) { theForm.__EVENTTARGET.value = eventTarget; theForm._EVENTARGUMENT.value = eventArgument; theForm.submit(); <script src="/AjaxChapter7/WebResource.axd?d=2k35oXVI5C1fsATKa8kOpQ2& amp;t=633008366579531250" type="text/javascript"></script> <script src="/AjaxChapter7/ScriptResource.axd?d=zmjix_F07KXpA6m02uaB_q52a3TPiFz24p4h x51TaC3HYCrvlQk4ongK5kg1IR8XFf7DTDlMUGM-Uucre6H3Yy1K_8vru25LXaz6lsl_p0U1&t= 633051881703906250" type="text/javascript"></script> <script src="/AjaxChapter7/ScriptResource.axd?d=zmjix_F07KXpA6m02uaB_ q52a3TPiFz24p4hx5lTaC3HYCrvlOk4ongK5kglIR8XFf7DTDlMUGM-Uucre6H3YlDyFBKNihsy-0GXMoZEYtgl&t=63305l88l703906250" type="text/javascript"></script> <script src="/AjaxChapter7/ScriptResource.axd?d=zmjix_F07KXpA6m02uaB_ q52a3TPiFz24p4hx5lTaC3HYCrvl0k4ongK5kglIR8XFf7DTDlMUGM-Uucre6H3Y90mwbS8Igy_KW_ 7MLdflsol&t=63305l88l703906250" type="text/javascript"></script> <div> <script type="text/javascript"> //<![CDATA[ Sys.WebForms.PageRequestManager._initialize('ScriptManagerl', document.getElementById('forml')); Sys.WebForms.PageRequestManager.getInstance()._updateControls(['tUpdatePanell'], <u>Market Summary:</u> <br /><br /> <div id="UpdatePanell"> <td><span id="Labell">DJIA</span></td> <td align=right><span id="lblDowJones">l2000</span></td> </tr> <tr> <td><span id="Label2">NASDAO</span></td> <td align=right><span id="lblNasdaq">2500</span></td> </tr> <tr> <td><span id="Label3">S&P 500</span></td> <td align=right><span id="lblSnp">l400</span></td> </tr> </table> <div id="UpdateProgressl" style="display:none;"> Updating... <span id="Timerl" style="visibility:hidden;display:none;"></span> <script type="text/javascript"> <!-- Sys.Application.initialize(); Sys.Application.add_init(function() { $create(Sys.UI._UpdateProgress, {"associatedUpdatePanelId":null,"displayAfter" :500,"dynamicLayout":true}, null, null, $get("UpdateProgress1")); Sys.Application.add_init(function() { $create(Sys.UI._Timer, {"enabled":true,"interval":2000,"uniqueID":"Timer1"}, null, null, $get("Timer1")); The ASPNET AJAX server controls emit JavaScript functions that copy and build a new innerHTML property of the <span> or <div> tags that contain the value getting updated. They are also responsible for generating a request on XMLHttpRequest and a callback for when the client request is complete. The callback then builds HTML code to put on the innerHTML property of the named <span> or <div> tags. This is basically how the UpdatePanel works under the hood. It uses Sys.WebForms.PageRequestManager to set up an asynchronous callback. These scripts are all automatically generated by the ScriptManager. Near the end of the source in the last lines of script in the page, you can also see the parameters of the Timer control being passed via JavaScript with the interval set to two seconds and the ID of the control being Timer1. Delving deeper into the generated script details piece by piece would fast take us beyond the scope of this chapter. If you are interested in having a more in-depth understanding of the inner workings of these script blocks on the page, you can view them by using either an HTTP sniffer, the JSView plug-in for FireFox (https://addons.mozilla.org/ en-US/firefox/addon/2076), or other third-party tools designed to capture the browser output. |
Post a comment