Hey, Scripting Guy! How Can I Automatically Move the Focus as Users Type in an HTA?
I have an HTA that we use for creating and modifying user accounts. In that HTA we have a couple of phone number fields; each of these fields consists of three text boxes (one for the area code and two for the phone number). I’d like to set this up so that, as soon as someone has typed three digits into the area code box the cursor automatically jumps to the first phone number box; as soon as someone types three digits in that text box I’d like the cursor to automatically jump to the third and final text box. How can I do that?
Hey, TJ. Wow. Gee, that’s a tough one, TJ and, to be honest, we don’t see how we can answer that; in fact, we aren’t even sure that there is an answer to that question. To tell you the truth, we feel really bad about that, and we feel even worse that we won’t be able to answer anyone’s question today. But that’s just the way it goes; we’ll try again tomorrow. Sorry.
And no, this has nothing to do with the Scripting Guy who writes this column intending to sneak out early in order to catch today’s tiebreaker game between the San Diego Padres and the Colorado Rockies. You say that San Diego and Colorado are playing today, with the winner moving on and the loser going home? We had no idea; in fact, we thought the baseball season ended a long time ago. How about that? We —
OK, so you caught us: we are planning on sneaking out early so that we can go home and watch the baseball game. And so we’ll make a deal with you TJ: we’ll show you how to automatically move the focus in an HTA and, in return, if our manager calls looking for us you tell him we’re in a meeting, a meeting that will last the rest of the day. Deal? Deal.
OK, here’s our end of the bargain:
If Len(TextBox1.Value) = 3 Then
If Len(TextBox2.Value) = 3 Then
<input type="text" name="TextBox1" size="10" maxLength="3" onKeyUp="TextBoxCheck">-
<input type="text" name="TextBox2" size="10" maxLength="3" onKeyUp="TextBoxCheck2">-
<input type="text" name="TextBox3" size="10" maxLength="4">
Let’s see if we can figure out how this baby works. (And let’s see if we can do so in 15 minutes or less.) To begin with, you might have noticed that we have three text boxes in the body of our HTA. (Just to add that extra special little touch, we’ve also put hyphens between each box, making the whole thing look a little more like a phone number.) Let’s take a look at the HTML tagging for text box No. 1:
<input type="text" name="TextBox1" size="10" maxLength="3" onKeyUp="TextBoxCheck">
As you can see, this is nothing more than your basic <INPUT> tag, along with the following five parameters:
type=”text”. This is just standard HTML to indicate that we want to use a text box control and not, say, a button or checkbox.
name=”TextBox1”. This is the name given to our text box; each text box has to have a unique name so that we can refer to the individual control boxes. (And, yes, now that you mention it, the Scripting Guys did come up with the name “TextBox1” all by ourselves. How did you know?)
size=”10”. The size property simply specifies the width of the text box, in characters. We picked 10 because … well, just because.
maxLength=”3”. This is a very useful property to know about: maxLength specifies the maximum number of characters that can be typed into the text box. Because a U.S. area code never has more than 3 digits, we set the maxLength of the text box to 3. Once you’ve entered 3 characters into the text box you can pound the keyboard all you want; you’ll never be able to wedge a fourth or fifth character into the box. Never.
onKeyUp=”TextBoxCheck”. The onKeyUp event is fired any time the focus is in the text box and someone presses and releases a key on the keyboard. The very moment that key is released the onKeyUp event is fired and our HTA immediately runs the subroutine TextBoxCheck (which we’ll discuss in just a second).
And then we have similar HTML tagging for our other two text boxes. But it is getting late, so we’ll let you figure out that part for yourself. (It’ll give you something to do while we’re at our, uh … meeting.)
In addition to the three text boxes, our HTA also has three subroutines. The first subroutine, Window_OnLoad, is automatically called any time the HTA is loaded or refreshed. As you can see, this subroutine does only one thing: it places the focus (the cursor) in TextBox1. Why did we do that? That’s easy: for this very simple HTA, that ensures that each time you run the application the focus will be in the first text box. In turn, that means you can start the HTA and immediately begin typing the area code.
This isn’t something that you have to do; we just thought it was another one of those nice little touches.
Our next two subroutines (TextBoxCheck and TextBoxCheck2, two more names we Scripting Guys came up with ourselves) represent the heart and soul of our little HTA. Let’s take a peek at the TextBoxCheck subroutine which, as you recall, is triggered any time a user types something in the text box set aside for the area code:
If Len(TextBox1.Value) = 3 Then
So what’s going on here? Well, each time someone types something in the text box we use the VBScript Len function to see how many characters, in total, have been typed into the box. (That is, how many characters are in the text box’s Value.) Suppose the length (number of characters) is 3. As it turns out, that’s the maximum number of characters allowed in the text box (and, not coincidentally, in an area code). Therefore we do two things:
First, we move the focus from TextBoxt1 to TextBox2. That’s what the code TextBox2.Focus is for.
Second, we select any existing text in TextBox2. We don’t have to do that, but that allows you to start typing and automatically replace any existing text in TextBox2. If you don’t like that feature then simply remove the line TextBox2.Select.
See how that works? You type the first character in the text box and, the moment you release the key, the subroutine is executed. Inside that subroutine we check to see how many characters have been typed in the text box. So far we have just 1 character in there, so nothing happens. Type a second character in the text box and, again, nothing happens. (Why not? Because nothing is supposed to happen, not unless there are 3 characters in the box.) Type a third character, however, and upon releasing the key, the focus will immediately jump to TextBox2.
Which is just exactly what we wanted it to do.
Note. As you probably guessed, the subroutine TextBoxCheck2 is very similar. The only differences? For one, this subroutine is fired each time something is typed into TextBox2; for another, when 3 characters have been entered into the text box the focus jumps to TextBox3.
That should do it, TJ. You could, of course, add in even more elaborate checking, to ensure that only numbers are typed into the boxes, but that’s an exercise we’ll save for another day.
Uh, never mind. As it turns out, the Scripting Editor doesn’t like us to say that we’ll save something for another day. “You say that all time,” she huffed, “and then half the time you never followed through.” Just to make her happy (needless to say, our sole purpose in life is to make the Scripting Editor happy) we traveled back in time and wrote a Hey, Scripting Guy! column that shows one way you can restrict the characters that can be typed into a text box.
And then, just for the heck of it, we traveled forward in time in order to see who’s going to win this year’s World Series. If you’re a Boston fan, well, you might want to limit the amount you bet on your beloved Red Sox. Just a little money-saving advice from the Scripting Guys.
Oh, and in case you’re wondering, the Scripting Guy who writes this column is predicting that the Cleveland Indians will win this year’s World Series. And you’re right: Cleveland is definitely not the favorite, and the Scripting Guy who writes this column is risking public ridicule by making such a prediction. But that’s OK; after all, if he’s wrong he’ll just travel back in time and rewrite his prediction, inserting the name of the team that really will win the World Series this year.
But there’s no time for time-travel now; instead, the Scripting Guy who writes this column is off to a meeting. (Remember, a deal’s a deal.) See you tomorrow.