Hey, Scripting Guy! Question

Hey, Scripting Guy! Sometimes you go to a Web page and you’ll see a text box that includes some instructions, something like “Please type a description in this box.” When you click on the text box, those instructions disappear; however, if you click on the box, don’t type in a description and then click somewhere else, then the instructions reappear. How can I do that same thing in an HTA?

-- AJ

SpacerHey, Scripting Guy! AnswerScript Center

Sorry; the Scripting Guy who writes this column is a little out of breath this morning; that’s because he was in a race around 6:30 AM, and hasn’t fully recovered. And in case you’re wondering, that’s a race he wasn’t expecting to be in, a race he didn’t realize he even was in, and a race in which he was soundly and decisively defeated.

Sometime in the past month or so the Scripting Guys began starting off each day by eating a ceremonial doughnut. The ritual works like this. Each morning, on his way to work, the Scripting Guy who writes this column stops at the store and buys doughnuts. And each morning the remaining team members eat those doughnuts. Do any of these remaining team members ever buy doughnuts? Do any of these remaining team members at least help pay for these doughnuts? Let’s put it this way: do any of these remaining team members ever do anything?

Note. Yes, this is exactly like the story of the Little Red Hen. “Who will help me buy these doughnuts?” says the Little Red Hen who writes this column. No answer. “Who will help me pay for these doughnuts?” says the Little Red Hen who writes this column. “Now, who will help me eat these doughnuts?” says the Little Red Hen who writes this column.

You can figure out the rest on your own.

At any rate, this morning the Scripting Guy who writes this column was grabbing a couple of doughnuts out of the doughnut case when he noticed an older woman taking a muffin out of the muffin case. (He noticed her because, for some reason, it’s very unusual for him to ever see anyone who’s older than he is. That hasn’t always been the case, but over the past few years something seems to have changed.)

Having grabbed his two doughnuts the Scripting Guy who writes this column began making his way towards the only open cash register. As he did so, he noticed that the muffin lady was scurrying to catch up to and then pass him. Unfortunately, she wasn’t particularly fast, and the Scripting Guy who writes this column was able to keep pace with her, even though he was moseying along in his typical fashion. (In his defense, however, he was on his way to work; it goes without saying that he was in no hurry whatsoever.)

As they approached the checkout stand, the lady took a desperate lunge and cut in front of the Scripting Guy who writes this column, a Scripting Guy who had to stop abruptly to make sure he didn’t crash into the woman. The muffin lady paid for her purchase and left. The Scripting Guy who writes this column then did the same thing, calculating that the muffin lady had saved nearly 30 seconds by getting to the checkout stand ahead of him.

And yes, that means that the Scripting Guy who writes this column could have saved 30 seconds of his own valuable time by forcing the issue and trying to beat the muffin lady to the checkout stand. But the Scripting Guy who writes this column lives such an exciting, fun-filled life that he decided he could afford to waste 30 seconds. And so he did.

Of course, that doesn’t mean that the Scripting Guy who writes this column can always afford to waste 30 seconds out of his life. After all, that might not leave time for his other daily rituals, like the one in which he tells people how to create a text box that displays a default message, causes that message to disappear when the text box gets the focus, then causes that message to reappear if the user doesn’t end up entering a new value in the box.

Not sure what that actually means? Then copy the following code, paste it into Notepad, save the resulting file as an HTML Application (HTA), and then give it a try for yourself:

<SCRIPT LANGUAGE="VBScript">

Sub TextBoxEnter
    If TextBox1.Value = "Please enter a value here." Then
        TextBox1.Value = ""
    End If     
End Sub

Sub TextBoxLeave
    If TextBox1.Value = "" Then
        TextBox1.Value = "Please enter a value here."
    End If     
End Sub

</SCRIPT>

<body>
    <input type="text" name="TextBox1" size="50" value="Please enter a value here." 
     onFocus = "TextBoxEnter" onFocusOut="TextBoxLeave"><p>
    <input type="text" name="TextBox2" size="50">
</body>

Good idea: let’s take a closer look at the code and see if we can figure out how this HTA works. To begin with, it’s a very simple little HTA; for one thing, the body consists of just two controls (a pair of text boxes). One text box – which we named TextBox2 – is just a plain old text box; that’s why the HTML tagging is so concise:

<input type="text" name="TextBox2" size="50">

The other text box, which we named TextBox1 (and no, we didn’t hire a consultant to help us; we came up with these names all by ourselves) is a little fancier:

<input type="text" name="TextBox1" size="50" value="Please enter a value here."
onFocus = "TextBoxEnter" onFocusOut="TextBoxLeave">

So what is all that fancy stuff? For starters, we need to have a default value assigned to this text box; when you first open the HTA we want the text box to display the message Please enter a value here. That’s why we added the value parameter, like so:

value="Please enter a value here."

In addition to having a default value, we also need this text box to respond to two different events: onFocus, an event triggered any time someone clicks onto or otherwise selects the text box; and onFocusOut, an event triggered any time someone clicks out of or otherwise moves the focus away from the text box. When either of those events occur we need to run the appropriate subroutine; each time the text box gets the focus we want to run a subroutine named TextBoxEnter, and each time the text box loses the focus we want to run a subroutine named TextBoxLeave.

Note. OK, for those subroutine names we did have to hire a high-priced consulting firm. But usually we come up with our own names for everything.

Which explains how we ended up with family members and pets that have names like the Scripting Son and the Scripting Dog.

As you might expect, all the fun stuff occurs inside those two subroutines. Let’s start out by looking at the subroutine that runs any time the text box gains the focus:

Sub TextBoxEnter
    If TextBox1.Value = "Please enter a value here." Then
        TextBox1.Value = ""
    End If     
End Sub

By default, our text box displays the message Please enter a value here. That’s fine; after all, that’s what we want the text box to display. However, we don’t want to always display that message; if someone clicks inside the text box we’d like that message to disappear. (Otherwise they’d have to select the message, delete it, and then start typing in a value.) So how do we make the message disappear? That’s easy; we simply set the value of the text box to an empty string:

TextBox1.Value = ""

Note, however, that we don’t set the value of the text box to an empty string any time that control gets the focus; instead, we “reset” the text box only if the message “Please enter a value here.” happens to be displayed. Why do we do that? Well, suppose someone enters a value like the following into the text box:

Pharmaceutical Research Division, Fabrikam Corp

As you can see, the period was left off the end; the value typed into the box should have really been this:

Pharmaceutical Research Division, Fabrikam Corp.

But that’s no big deal; after all, the user can just click at the end of the text box and then type in the missing period. Or, to be a little more precise, they can do that as long as we don’t automatically delete the value of the text box each time the text box regains the focus. That’s why we don’t automatically reset the value of the text box; we do that only if the default value (“Please enter a value here.”) is displayed. Otherwise any time someone clicked in the text box we’d erase everything they’d previously typed into the box. That might be OK. But, then again, it might not be.

Now, what happens when the text box loses the focus? This is what happens:

Sub TextBoxLeave
    If TextBox1.Value = "" Then
        TextBox1.Value = "Please enter a value here."
    End If     
End Sub

In effect, our onFocusOut subroutine is a mirror image of the onFocus subroutine. This time around, we check to see if the value of TextBox1 is equal to an empty string. If it is, that means that nothing at all has been typed into the text box. As a result, we set the value of the box to the default message: Please enter a value here. That’s ensures that we never have a truly empty text box; if the box is empty we redisplay the default message. And what do we do if something other than the default value has been typed into the text box? Nothing; as long as the text box has something in it we simply leave the value alone. Combined, these two subroutines should provide the very behavior you were looking for.

Now, to tell you the truth, the Scripting Guy who writes this column wasn’t all that distraught about the muffin lady having beaten him to the checkout stand; in fact, he really didn’t pay much attention to it. Apparently, however, the muffin lady did give it some thought; as the Scripting Guy who writes this column left the store the muffin lady was waiting for him. “I’m sorry I raced in front of you,” she said. “That was very rude of me. I should have let you go ahead of me.”

She should have let him get ahead of her? You know, if you’ve ever wondered how far the Scripting Guy who writes this column has fallen that should answer your question: little old ladies are now apologizing for being too fast and not letting him get ahead of them.

Gosh, if little old ladies are passing him by that means that the Scripting Editor might soon be passing him by as well. Now there’s a scary thought ….