Wrox Home  
Search
Professional ASP.NET 2.0 Server Control and Component Development
by Shahram Khosravi
August 2006, Paperback


Revisting the GetNotificationId JavaScript function

Now, revisit Listing 1 to discuss part of this code listing not yet covered, as highlighted in Listing 7.

Listing 7: The OnPreRender method revisited
protected override void OnPreRender(EventArgs e)
{
  DetermineRenderClientScript();
  if (renderClientScript)
  {
    string js = Page.ClientScript.GetCallbackEventReference(
             this,
             "GetNotificationId('"+ClientID+"')",
             "AjaxNotifierCallback",
             "'" + ClientID + "'", true);
    string js2 = "function DoCallback () {" + js + ";}";
  
    Page.ClientScript.RegisterClientScriptResource(typeof(AjaxNotifier), 
             "CustomComponents.AjaxNotifier.js");
    Page.ClientScript.RegisterClientScriptBlock(typeof(AjaxNotifier), 
             typeof(AjaxNotifier).FullName + "DoCallback", js2, true);
    Page.ClientScript.RegisterStartupScript(typeof(AjaxNotifier), 
             typeof(AjaxNotifier).FullName + "WebDoCallback", js,true);
  }
  base.OnPreRender(e);
}

As the highlighted portion of Listing 7 shows, the GetNotificationId JavaScript function is assigned to the task of determining the notification ID that the client passes to the server. Recall that this notification ID is the ID of the latest notification that the current user has seen. The following code listing presents the implementation of the GetNotificationId JavaScript function:

function GetNotificationId(ajaxNotifierId)
{
  var ajaxNotifier = document.getElementById(ajaxNotifierId);
  return ajaxNotifier.notificationId;
}

As the highlighted code in Listing 7 illustrates, OnPreRender passes the value of the ClientID property of the AjaxNotifier control to the GetNotificationId JavaScript function. As this code shows, GetNotificationId passes this value to the getElementById method of the document DOM object to access the containing HTML element of the AjaxNotifier control. GetNotificationId then returns the value of the notificationId attribute of the containing element. Notice that this attribute is a custom HTML attribute that holds the notification ID of the latest notification the current user has seen.

As the highlighted code in Listing 7 shows, OnPreRender registers the AjaxNotifierCallback JavaScript function as the callback for the client callback requests. This function is automatically called when the server response arrives. Listing 8 contains the implementation of the AjaxNotifierCallback JavaScript function.

The AjaxNotifierCallback function first calls the CreateXmlDocument JavaScript function discussed in the previously mentioned Chapter 27 to create an XML store:

var xmlDocument = CreateXmlDocument(); 

It then loads the XML document that it has received from the server to the XML store:

xmlDocument.loadXML(result); 

Next, it accesses the document element of the XML document. As shown in Listing 6, the document element is the <notification> element:

var notification = xmlDocument.documentElement; 

It then accesses the first child element of the document element. As shown in Listing 6, the first child element is the <id> element:

var notificationId = notification.childNodes[0].text; 

Next, AjaxNotifierCallback accesses the containing HTML element of the AjaxNotifier control:

var ajaxNotifier = document.getElementById(context);

Recall that the containing HTML element of the AjaxNotifier control has a custom attribute named notificationId that holds the notification ID of the latest notification that the current user has seen. AjaxNotifierCallback checks whether the notification ID of the notification that it has received from the server is different from the notification ID of the latest notification that the user has seen. If so, it assigns the new notification ID to the notificationId attribute of the containing HTML element of the AjaxNotifier control:

ajaxNotifier.notificationId = notificationId;

AjaxNotifierCallback then calls the InitializeDetailsPopup JavaScript function discussed in the previously mentioned Chapter 26 to initialize the pop-up dialog:

InitializeDetailsPopup(context);

Next, it accesses the text content within the opening and closing tags of the second and third child elements of the <notification> document element. As shown in Listing 6, these two child elements are the <source> and <summary> elements:

	var notificationSource = notification.childNodes[1].text; 
	var notificationSummary = notification.childNodes[2].text; 

Next, AjaxNotifierCallback generates the HTML that displays the new notification:

var content = "<r>" +
                  "<td colspan='2'>" +
                    "<p><center><b>New Message</b></center></p>" +
                    "<p><b>From: </b>"+notificationSource+"</p>" +
                    "<p><b>Message:</b><br/>"+notificationSummary+"</p>" +
                  "</td>" +
               "</r>";

It then calls the DisplayDetailsPopup function to display the HTML in the details pop-up dialog:

DisplayDetailsPopup (content);

Finally, AjaxNotifierCallback calls the setTimeout JavaScript function:

setTimeout(DoCallback,6000);

As shown in Listing 1, the DoCallback JavaScript function runs the JavaScript code that makes the asynchronous client callback to the server to download the XML document that contains the latest posted notification. The AjaxNotifierCallback JavaScript function is automatically called when the page is loaded. This means that when the user downloads the page, the following sequence is automatically triggered:

  1. AjaxNotifierCallback is called.
  2. AjaxNotifierCallback pops up the dialog that displays the latest posted notification.
  3. AjaxNotifierCallback calls the setTimeout function.

The setTimeout function periodically calls the DoCallback function, which in turn runs the JavaScript code that makes a client callback request to the server to download the XML document that contains the latest posted notification. When the server response arrives, this JavaScript code, in turn, calls the AjaxNotifierCallback method, which repeats the same steps discussed before.

Listing 8: The AjaxNotifierCallback Method
function AjaxNotifierCallback(result, context) 
{ 
  var xmlDocument = CreateXmlDocument(); 
  xmlDocument.loadXML(result); 
  
  var notification = xmlDocument.documentElement; 
  if (notification.childNodes.length > 0)
  {
    var notificationId = notification.childNodes[0].text; 
    var ajaxNotifier = document.getElementById(context);
    if (notificationId != ajaxNotifier.notificationId)
    {
      ajaxNotifier.notificationId = notificationId;
      InitializeDetailsPopup(context);
      var notificationSource = notification.childNodes[1].text; 
     
      var notificationSummary = notification.childNodes[2].text; 
     
      var content = "<r>" +
         "<td colspan='2'>" +
           "<p><center><b>Notification</b></center></p>" +
           "<p><b>From: </b>"+notificationSource+"</p>" +
           "<p><b>Message:</b><br/>"+notificationSummary+"</p>" +
         "</td>" +
      "</r>";
      DisplayDetailsPopup (content);
    }
  }
  setTimeout(DoCallback,6000);
}

Try the following workflow to see for yourself how the AjaxNotifier works:

  1. Get the sample code files for the book Professional ASP.NET 2.0 Server Controls and Component Development and open the application that contains the code files for Chapter 29 in Visual Studio 2005.
  2. Run the application to access the AjaxNotifier.aspx page. Listing 4 shows the contents of this page. Notice that the AjaxNotifier automatically makes an asynchronous client callback to the server to retrieve the latest notification and displays the notification in the pop-up dialog as shown in Figure 1.
  3. Go to the Server Explorer window and access the database table named Notifications.
  4. Add a new notification record to the table. Notice that the AjaxNotifier automatically shows the latest notification.

When you first launch the application, AjaxNotifier displays all the notifications one after another because the current implementation of the AjaxNotifier doesn't store the notification ID of the latest notification that the user saw in the previous session. That's why AjaxNotifier resets this notification ID to zero every time you relaunch the application. You can easily fix this by storing the notification ID of the latest notification in the ASP.NET 2.0 Profile object.

This article is adapted from Chapter 29 "Developing Ajax-Enabled Controls and Components: More Ajax Patterns" of the book Professional ASP.NET 2.0 Server Control and Component Development by Dr. Shahram Khosravi (Wrox, August 2006, ISBN: 0-471-79350-7). Shahram is a senior software engineer, consultant, author, and instructor specializing in ASP.NET, Web services, .NET technologies, XML technologies, ADO.NET, C#, 3D computer graphics, Human Interface (HI) usability, and design patterns. He has more than 10 years of experience in object-oriented analysis, design, and programming. Shahram has written articles on the .NET Framework, ADO.NET, ASP.NET, and XML technologies for industry leading magazines such as Dr. Dobb's Journal, asp.netPRO magazine, and Microsoft MSDN Online. His other recent article on Wrox.com was ASP.NET 2.0 WebPartChrome.