Programmatically Creating Context-Sensitive Help on a Web PageBy Scott Mitchell
Last week's article aimed to simply lay the ground work for creating a context-sensitive help system and, as such, had a few shortcomings. Most noticeably, the help window appeared immediately when mousing over its associated region and disappeared immediately after mousing out of that region. This behavior introduced two usability issues: first, when moving the mouse over the screen, if you happened to pass over a help region the help window appeared, which could be jarring; second, if a help window contained links or was lengthy enough to require scrolling, when attempting to move the mouse from the help region to the help window, the mouse would leave the help region and the help window would disappear.
In addition to these two end user usability problems, the context-sensitive help system presented last week wasn't very user friendly for us,
the page developer. All of the script and
needed to be manually added to the web page to define the help windows and the
onmouseout event handlers for the help region. Ideally, all of the necessary script and markup could be added
programmatically, with a single line of code from the ASP.NET code-behind class.
In this article we'll see how to improve upon the rudimentary context-sensitive help system from last week by fixing the aforementioned usability concerns and by creating an ASP.NET 2.0 class with methods to programmatically add the help windows and needed script for a given help region. Read on to learn more!
If you've not yet read Creating Context-Sensitive Help on a Web Page, please do so before continuing with this article...
Delaying Before Opening and Closing Help Windows
When mousing over a tooltip-enabled user interface element in a web page or Windows application, the tooltip doesn't immediately appear, but only after hovering over its help region for a short time. The context-sensitive help system explored in last week's article, however, immediately shows the help window when a help region is moused over. This immediacy can have a jarring effect for the user if they move their mouse across their browser screen. Even though they didn't intend for any context-sensitive help to popup, their mouse's flight across the screen may have inadvertently passed through one or more help regions, thereby causing the help window to display. Granted, these help windows quickly disappeared as the user continued to move their mouse across the screen, but the quick flash of the help window might confuse or annoy users.
To remedy this, we can introduce a slight delay before displaying a window. That is, when the user mouses over a help region, rather than display the help window immediately, we wait for half a second (or what have you) and then show the help window. If, in that half second waiting period, the user's mouse has left the help region, then we'd not show the help window.
function to perform a given expression after a specified number of milliseconds delay. When using
vital to understand that the function is non-blocking. That is, when the
setTimeout statement is reached,
setTimeout function are then executed without pause. In other words, the delay specified before executing the
specified expression is asynchronous. The control flow does not wait at the
setTimeout command until
the specified delay has passed.
To accomplish this, I broke out the
csi_showHelpFloatWindow - which displays a specified help window - into
csi_showHelpFloatWindow- accepts the same set of input parameters as before along with a new one,
waitDurationInMillisecondsparameter indicates how many milliseconds to pause between mousing over a help region and displaying its help window. This function calls the
csi_showHelpFloatWindowInternal- does the actual work of displaying the help window.
csi_showHelpFloatWindowis called and the
setTimeoutfunction instructs that the
csi_showHelpFloatWindowInternalfunction is to be called after, say, 500 milliseconds (half a second). If the user moves their mouse out of the help region before the 500 millisecond delay has expired, we do not want to display the help window. However, the
csi_showHelpFloatWindowInternalfunction will still execute, there's no way to cancel it based on the mouse movements.
Therefore, we use a flag variable that indicates whether or not the open command has
been cancelled - it's set to
csi_showHelpFloatWindow and to
true in the
onmouseout event handler of the help region. When the
csi_showHelpFloatWindowInternal function executes,
it only proceeds if the cancel flag is
false. Since there may be different help window types on a page (that is,
help windows with different windowIDs), a single
flag variable won't do. Rather, we need a flag for each unique help window type. This is accomplished through an array, as the
When the user mouses out of a help region, we need to set the flag (
true. This is accomplished by updating the
csi_hideHelpFloatWindow function (which, recall, is executed
from the help region's
This same pattern is repeated to add a delay when between when mousing out of a help region whose help window is open, and
closing that help window. This delay allows the user to move their mouse from the help region to the help window, where they
can interact with the help window (scroll through its contents, click a hyperlink, and so on). To facilitate this, another
flag array is used (
csi_cancelCloseArray), which is set to
false when leaving a help region (in
csi_hideHelpFloatWindow function) and set to
true when mousing over a help region or when
mousing over the help window itself. As with the delay before opening, this is accomplished by splitting the
into two functions:
csi_hideHelpFloatWindow- accepts an additional input parameter
waitDurationInMilliseconds, which indicates how many milliseconds to pause between mousing out of a help region and hiding its help window. This function calls the
csi_hideHelpFloatWindowInternal- does the actual work of hiding the help window.
csi_showHelpFloatWindow and the
onmouseover event of the help window set
the appropriate flag in
code library available for download at the end of this article for more information.
Adding Context-Sensitive Help Programmatically
There are a number of client-side tasks we need to complete in order to associate a help window with a particular region, including:
- The CSS styling for the help window (its
z-index, configuring it for absolute positioning, and so on)
- The help window markup (the
To implement this, I created a class named
ContextSensitiveHelp that contains the context-sensitive help-related methods.
ContextSensitiveHelp derives from the
To utilize its context-sensitive help-related methods in an ASP.NET page, adjust your ASP.NET page's code-behind class so
that it derives from
ContextSensitiveHelp rather than from
Using a Custom Base Class for your ASP.NET Page's
Code-Behind Classes for more information on this technique and its advantages.
ContextSensitiveHelp class contains a single page-level accessible method,
which has a variety of overloads. At minimum, you must pass this method:
- The Web control that serves as the help region (perhaps a Label Web control or an Image Web control),
- The windowID (an arbitrary string that is used to identify a help window for opening and closing the window), and
- The URL of the help web page to display in the help window
For example, to associate a help window with a Label control named
WelcomeLabel, you could add the following
line of code to the
Page_Load event handler:
To try out the
ContextSensitiveHelp class, download the project files available at the end of this article.
Conclusion & Looking Forward...
setTimeoutfunction to add a brief delay before showing a help window and how to leave the help window displayed after mousing out of the help region. Furthermore, we examined the
ContextSensitiveHelpclass, which provides a simple method for creating and associating a help window with a help region.
There are still a few shortcomings of the context-sensitive help system, though. For one, the help windows require an explicitly specified height and width, and do not adapt to their actual content. For example, consider a help window sized at 400x350, but whose help content contains just a few words. Ideally this help window would be smart enough to resize itself to, say, 200x150, to reduce the whitespace in the window. Additionally, if the help region is near the border of the browser (at the right or bottom), the help window will likely be cut off by the bottom or right of the browser. Ideally, the help system would be intelligent enough to position itself to the left if it was going to be cut off on the right or to raise its top position if it was going to be cut off at the bottom. Perhaps a future article will tackle these issues!