ColdFusion in Context: Field Help

Suppose your boss tells you that you have three days to add field-level help to an application. Here's one way to meet that deadline.

Consider the Requirement

If you have three days to perform this task, you want to modify the existing code to only a small extent. You need to let the user interact with something that is associated with the fields. And, you want to keep the amount of hand-coding to a minimum. In fact, it would be nice if you could automatically generate the hooks that tell the help facility that the user is interested in a given field; so, you can concentrate on the help text itself.

Browser limitations drive the kind of notification the user must give you to show interest in a field. It's tough without heroic measures to get Netscape to honor the mouseover javascript function for any object other than an image or a link. Adding an image for each field would make multiple changes to the appearance of the page; it would probably deform it to the extent that manual rework was needed. Turning the field label (not the input field itself) into a link provides the additional complication that some labels consist of multiple words, punctuation, or may not exist at all. This makes it hard to automate the process of inserting the hooks to these objects that you'll need to get the right help text to show. Besides, it would be nice to use the exact field name in case someone has been kind enough to publish a description of your database that could serve as a source for help text.

Once you decide on a way to let the user show interest in a field, you need a place to display the explanation of the field. Alert boxes disrupt normal operation, depending on how they're triggered. A pop-up window for help might be nice, but it can be hard to use javascript to dynamically flow text to an extra window in these security-conscious days without without rewriting that window completely whenever the text changes. Also, adding frames and pop-up windows can be tricky if the application already has frames.

Consider a Solution

Suppose you used the onFocus function to tell you that the user is interested in a field. This is supported by both major browsers and by multiple kinds of fields. Making your hooks part of existing fields gives you direct access to their names; no re-typing is necessary.

Sending help text to a field in its own form at the top of the page is an easy way to get text in front of the customer. It requires less effort to adjust the placement of one field than to make the application-specific changes needed for an extra window or frame. It's a solution that works.

Make a "Typical" Page

Put this code in normal.cfm. It contains examples of various field types.

<form name="Sample">
MyText: <input type="input" name="MyText">
MyTextArea: <textarea name="MyTextArea">default text</textarea>
MySelect: <select name="MySelect" multiple>
<option>have your cake</option>
<option>eat your cake</option>
</select>
<p>
MyRadioBox-A: <input type="radio" name="MyRadioBox" value="yes">
-B: <input type="radio" name="MyRadioBox" value="no">
&nbsp;&nbsp;&nbsp;
MyCheckBox-A: <input type="checkbox" name="MyCheckBox" value="red">
-B: <input type="checkbox" name="MyCheckBox" value="blue">
</form>

Add Focus Hooks

Copy the page to enhanced.cfm. Open it in a word processor. Insert this...

onFocus="explain(this); return false;"

...with a trailing space after each of the following scraps of text to make it part of each field. (The trailing space is needed to separate the insertion from the next attribute of the field.)

"<input "
"<cfinput "
"<textarea "
"<select "

You have just added a hook to each field. When the field receives focus, a javascript routine named "explain" will receive the name of the field (and its value, although that won't be needed). Here is the result for enhanced.cfm thus far:

<form name="Sample">
MyText: <input onFocus="explain(this); return false;" 
type="input" name="MyText">
MyTextArea: <textarea onFocus="explain(this); return false;" 
name="MyTextArea">default text</textarea>
MySelect: <select onFocus="explain(this); return false;" 
name="MySelect" multiple>
<option>have your cake</option>
<option>eat your cake</option>
</select>
<p>
MyRadioBox-A: <input onFocus="explain(this); return false;" 
type="radio" name="MyRadioBox" value="yes">
-B: <input onFocus="explain(this); return false;" 
type="radio" name="MyRadioBox" value="no">
&nbsp;&nbsp;&nbsp;
MyCheckBox-A: <input onFocus="explain(this); return false;" 
type="checkbox" name="MyCheckBox" value="red">
-B: <input onFocus="explain(this); return false;" 
type="checkbox" name="MyCheckBox" value="blue">
</form>

Add the Explanation

Now all that has to happen is for the "explain" routine to associate the field name with explanatory text. Insert the following code at the top of the page:

<form name = "Explanation">
<div align="center">
<h4>FIELD HELP - <input type="type" 
name="ShowIt" bgcolor="green" size="70"> - FIELD HELP</h4>
</div>
</form>

<script language = "javascript">
function explain(theField) {
theText = "";
if (theField.name == "MyText") {
theText = "This little piggy went to market";
}
else if (theField.name == "MyTextArea") {
theText = "This little piggy stayed home";
}
else if (theField.name == "MySelect") {
theText = "This little piggy had roast beef";
}
else if (theField.name == "MyRadioBox") {
theText = "This little piggy had none";
}
else if (theField.name == "MyCheckBox") {
theText = "And this little piggy cried bitterly all the way home";
}
document.Explanation.ShowIt.value = theText;
}
</script>

Consider Automation

Notice the repetition. The same text is added to every field; four lines of ColdFusion could perform the four global replace steps that you used a word processor to perform. A few more would get a list of fieldnames and use that list to generate the code above (with empty strings for the text). Try this technique by browsing normal.cfm and enhanced.cfm. Then automate it. =Marty=