Click here to Skip to main content
15,867,986 members
Articles / Web Development / HTML
Article

Context Sensitive Help using Client Callbacks - AJAX Style

Rate me:
Please Sign up or sign in to vote.
3.62/5 (8 votes)
25 Sep 20068 min read 39.4K   35   1
This article is all about providing Context Sensitive Help in a web page, asynchronously or AJAX style, using Client Callbacks in .NET 2.0.

Sample Image - ContextSensitiveHelp

Introduction

This article is all about providing Context Sensitive Help in a webpage, asynchronously or AJAX style, using Script Callbacks in .NET 2.0.

Scenario in brief

When you are filling an online form in an internet website, or while trying to enter the search\filtering criteria for various fields, one time or other, every one of us might have definitely expected for a brief description or help on what we are expected to do. Providing such information on demand would definitely make the user very comfortable.

This article on Context Sensitive Help deals on how it can be accomplished.

The following sequence of steps describe the scenario in brief:

  • You are trying to fill a form in a website.
  • You see a screen element\form field to enter the value for.
  • You are perplexed or confused.
  • You move the mouse over the element name.
  • The cursor symbol reveals your expression. A question mark is shown next to the cursor.
  • Click on it.
  • Dynamically, Help appears, that is help\description related to the screen element clicked.

Problem

How to fetch the Help text dynamically?

Solutions I have seen

Solution 1

I have seen some websites refreshing or posting back the page when the user clicks on an element, to provide the description or help text in a predefined separate region. This is definitely a heavy approach. Consider a help text that contains just 10 words. We are posting some kilo bytes of data to just fetch a few bytes of data.

Solution 2

Another solution I have seen is load the help text of all the screen elements while loading the page and store at client side in a JavaScript array. On the click event of each screen element, a JavaScript call to fetch the help text from the array is made, passing the index of the screen element in hand as the parameter. This seems to be OK for a page where there are only a few screen elements, but the downside comes for web pages where the number of screen elements runs to hundreds. I have seen an application with a page that has got 104 fields and the help text for each field is not less than 4 lines of 15 words each. So just imagine the size of the help text to be loaded along with the page. Definitely, a very heavy task! Googling for Context Sensitive Help provides you with many other solutions which more or less do the same.

Solution provided in this article

When the user clicks on a screen element for help, an asynchronous call is made to the server using the Client Call back features of .NET, the required help text is retrieved from an XML file located on the server, and returned to the client. There is a round trip to the server, but the entire page is not posted and there is no flickering as well.

Behind the scenes

When we type a URL in the address bar and press the Enter button in the browser, the browser runs an HTTP command, opens a socket with the specified IP address, sends the packets, and waits for the response. The response is displayed by the browser. The same process is repeated when the page is posted back. In this case, the page output is clearly re-displayed. Now we do not want to post the whole page to the server and refresh the entire page. We just want to dynamically display\change\update a part of it, getting the data from the server with out causing any flickering. So, we have two challenges here.

  • Establish an HTTP connection with the required IP address to get the data.
  • Refresh the page dynamically.

The first task is handled by .NET 2.0 script callbacks, and the second task is handled by DHTML.

So, all that we have to do is:

  • The ICallbackEventHandler should be inherited by the Webpage.
  • Get the Callback Event Reference and register the Client Script Block.
  • Implement the RaiseCallbackEvent method of the ICallbackEventHandler.

To use ASP.NET 2.0 script callbacks, you need to implement the ICallbackEventHandler Interface. The reason for this is discussed in the later part of the article. The trigger element of a page, that is the element of a page which fires some event and for which we need to fetch data from the server, needs to be bound to some JavaScript code which will retrieve the input data from the current page and provide a call to the system provided script function. This function opens an HTTP connection to the corresponding remote ASP.NET page. The ASP.NET runtime detects a callback invocation, and checks to see if the page implements the ICallbackEventHandler. If implemented, the runtime executes the RaiseCallbackEvent method on the page. The return values of the server side method is passed back to the client as a response to the previous request. On the client, the response gets passed to a user-defined JavaScript callback function that can then update the user interface via DHTML. As it can be observed, the roundtrip occurs but the whole page is not posted back. The good thing here is that the user can continue working with the controls in the page while the request is being processed in parallel.

Every thing in one paragraph is like swallowing a pizza piece at once. Let us bite the pizza in small pieces and enjoy the taste.

Code walkthrough

The process described above is explained with pieces of code as below:

Inheriting the ICallbackEventHandler interface by the page:

C#
public partial class _Default : PageManager, ICallbackEventHandler
{
    ………………………
    …………………..
    …………………..
}

Getting the reference to the system provided script:

C#
strHelpReference = Page.ClientScript.GetCallbackEventReference(this,
                                                              "arg",
                                           "JavaScriptCallBackHelp",
                                                          "context"
                                                                  );

Registering this client script block:

C#
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                      "CallBackHelp", strHelpScript, true);

This JavaScript method is bound to some event in the page. For example, the click event of the label\text “title:” on the page is associated to the GetContextSensitiveHelp JavaScript method which triggers the CallBackHelp JavaScript method. As given above, this holds the reference to the system generated script method that serves the callback. Once the processing is done at the server side, the JavaScript method JavaScriptCallBackHelp is triggered, passing the result returned from the server-side method as the parameter.

The code for retrieving the help text associated with the element clicked is written in the RaiseCallbackEvent.

C#
public void RaiseCallbackEvent(string strEventArgument)
{
    try
    {
        char[] charSeperator = { '#' };

        //If the aruguement starts with help, it indicates 
        //that the call back event occured 
        //for providing Context Sensitive 
        //help for the selected screen element.
 
        if (strEventArgument.StartsWith("Help"))
        {
            strCallBackResult = LoadContextHelp(strEventArgument.Remove(0, 4));
        }
    }
    catch (Exception ex)
    {
        Response.Write(ex.ToString());
    }

}

The LoadContextHelp method is the one that actually fetches the help text associated with the screen element. In the attached code, I am fetching the help text from an XML file. This method can be implemented in any other way you wish.

The result is assigned to the string variable strCallBackResult, which is returned by the method GetCallbackResult. The triggering of the RaiseCallbackEvent and the GetCallbackResult methods is done by the runtime.

Overview of other components in the application attached

A user control HelpControl is created to hold the markup of the Help section.

A separate class XmlMessages is created. This holds the path to the XML file, and the whole XML context is an XmlDocument object which is exposed as the property of the XmlMessages class. Various methods are provided to fetch the required node\nodes from the XML file using Xpath.

A separate class CacheManager is created to provide methods to load and refresh the cache data.

A separate PageManager class is to be inherited by all the web pages in the application. In the Init method of this class, the CacheManager methods are triggered to load the data from the Cache or refresh the data in the Cache.

Details on the JavaScript functions used

The title and description of the help text is returned in the same parameter, concatenated by the character “#”. The JavaScript callback method JavaScriptCallBackHelp splits the returned result in to Title and Description, and triggers the ShowHelp JavaScript function in the helpfunctions.js JavaScript file.

JavaScript
function JavaScriptCallBackHelp(help, context)
{
    var helpArray = new Array();
    helpArray = help.split('#');
    ShowHelp('objHelpControl',helpArray[0],helpArray[1]);
}

The JavaScript function ShowHelp sets the div related to the title and the description, and changes the style of the container div to block to display the help.

JavaScript
function ShowHelp( strPrefix, strTitle, strMessage ) 
{    
    var objContainer = document.getElementById(strPrefix + '_csh_container');
    var objTitle = document.getElementById(strPrefix + '_csh_Title');
    var objHelp = document.getElementById(strPrefix +  '_csh_Description');
    
    objContainer.style.display = 'block';
    objTitle.innerHTML = strTitle;    
    objHelp.innerHTML = strMessage;    
}

When the cross image is clicked, the function SetHelpClosed is triggered to close the help section. This is done by changing the display style of the container div to none.

JavaScript
function SetHelpClosed(objElement) {
    /* get the container object */
    objParentObject = objElement.parentElement;        
    while (objParentObject.id=="" && objParentObject != null)
        objParentObject = objParentObject.parentElement;        
    
    if (objParentObject == null) return false;
    
    objParentObject.style.display="none";       
}

There are a few other JavaScript functions that are used for making the help section draggable. The details of the same are not in the scope of this article.

Points of interest

In the attached code, in addition to Script Callbacks, one can observe the practical implementation of various concepts like:

  • Base class implementation
  • Caching
  • Themes (using skin file for the controls)
  • Using the XmlDocument object and Xpath
  • User Controls

Conclusion

The Context Sensitive Help feature might not be applicable to all web pages. This feature should be provided based on the type of webpage and jargon used in the webpage. For example, in some business specific intranet web sites like Insurance, where there will be hundreds of elements in a single webpage, implementing this feature would be very appropriate. Implementing this feature should not be based on the number of screen fields any way. Even if there are only a few fields, if it is required, yes, definitely provide it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUpdating other controls Pin
JSCy1-Feb-10 20:23
JSCy1-Feb-10 20:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.