Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I configure a pair of dropdown lists in an HTA so that, when I change the selection in the first list, the options available in the second list also change?

-- PC

SpacerHey, Scripting Guy! AnswerScript Center

Hey, PC. Before we get going today, we’d like to make it clear that the Scripting Guy who writes this column isn’t the least bit tired. Sure, he and the Scripting Son went to the midnight showing of The Simpsons Movie last night, which meant that the Scripting Guy who writes this column didn’t get to bed until 2:15 AM, then had to get up less than four hours later in order to get to work and write this column. But why would that make him tired? Sure, staying up all night might make some old guy tired. But the Scripting Guy who writes this column? He’s not the least bit … um, what was that word again? Right. Tired. He’s not the least bit tired.

Not the bit least.

Um, not the least bit.

At any rate, seeing as how the Scripting Guy who writes this column is bright-eyed and bushy-tailed, and seeing as how he did remember to put on pants this morning (hold on a second … yes, he did), let’s see what we can do to address PC’s question. Which was … it’s on the tip of our tongue … oh, right. PC has an HTML Application (more familiarly known as an HTA) that features a pair of drop-down lists. When he makes a selection in the first list, he’d like the options in the second list to dynamically change in response to that choice. How can he do that? We have absolutely no idea. Good night; see you in the morning.

Wait a second; don’t go. It turns out that we have at least one idea as to how he can do this:

<Script Language="VBScript">
    Sub RunScript
        For Each objOption in DynamicOptions.Options
            objOption.RemoveNode
        Next 

        If PickCategory.Value = "Characters" Then
            arrValues = Array("A", "B", "C", "D", "E")
        End If

        If PickCategory.Value = "Numbers" Then
            arrValues = Array("1", "2", "3", "4", "5")
        End If

        For Each strValue in arrValues
            Set objOption = Document.createElement("OPTION")
            objOption.Text = strValue
            objOption.Value = strValue  
            DynamicOptions.Add(objOption)
        Next     
    End Sub
</Script>

<select size="1" name="PickCategory" style="width:100px" onChange="RunScript">
    <option value="Characters">Characters</option>
    <option value="Numbers">Numbers</option>
</select>

<P>

<select size="1" name="DynamicOptions" style="width:100px">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
    <option value="D">D</option>
    <option value="E">E</option>
</select>

As you can see, there’s really not too much to this particular HTA. (If you aren’t sure what an HTA even is then you might want to take a peek at our HTA Developers Center.) For example, the body of our HTA contains only a pair of drop-down lists. The first drop-down list is named PickCategory and includes just two options:

Characters (the default value)

Numbers

The premise here is simple: the user is going to select one of these two options. If the user selects Characters then, on-the-fly, we’ll display a series of letters as the individual options available in our second drop-down list (which we christened DynamicOptions). If the user selects Numbers, we’ll display a series of numbers as the options available in the second drop-down list. Each time we change the value of PickCategory we’ll run a subroutine named RunScript; hence the parameter onChange="RunScript":

<select size="1" name="PickCategory" style="width:100px" onChange="RunScript">
    <option value="Characters">Characters</option>
    <option value="Numbers">Numbers</option>
</select>

That second drop-down list, as we noted, is named DynamicOptions; when the HTA opens it displays, by default, a series of characters as the drop-down options (if you aren’t familiar with the HTML tagging for creating a drop-down list then take a look at one of our HTA tutorials). The complete tagging for this drop-down list looks like this:

<select size="1" name="DynamicOptions" style="width:100px">
    <option value="A">A</option>
    <option value="B">B</option>
    <option value="C">C</option>
    <option value="D">D</option>
    <option value="E">E</option>
</select>

Of course, these default options aren’t set in stone; instead, they’re going to change each time the user makes a new selection in the PickCategory drop-down. How? Don’t worry; we’ll tell you how.

Zzzzz …

Sorry. Just resting our eyes.

Now, where were we? That’s odd; we have absolutely no idea what we were just talking about. But that’s all right; let’s just go ahead and talk about the subroutine RunScript, the subroutine that runs any time the user makes a new selection in the PickCategory drop-down list.

Zzzzz …

Um, so what does happen in the RunScript subroutine, you ask? To begin with, we use this block of code to remove all the existing options from the DynamicOptions drop-down:

For Each objOption in DynamicOptions.Options
    objOption.RemoveNode
Next

Why bother with this? That’s easy: each time we make a change in the first drop-down list we want to completely replace all the options shown in the second list. The easiest way to do that is simply to remove all the existing options and then start adding new options from scratch.

Speaking of which, our next step is to determine the actual value that was selected in drop-down list 1, then begin the process of assigning the appropriate set of options to drop-down list 2. (To that end, the first thing we’ll do is put all those options into an array named arrValues). The following block of code determines whether or not the value Characters was selected in our first drop-down; if so, it then assigns a series of letters to arrValues:

If PickCategory.Value = "Characters" Then
    arrValues = Array("A", "B", "C", "D", "E")
End If

Meanwhile, this block of code assigns a series of numbers to arrValues, but only if Numbers was selected in drop-down 1:

If PickCategory.Value = "Numbers" Then
    arrValues = Array("1", "2", "3", "4", "5")
End If

Once we’ve assigned the appropriate set of values to arrValues we then use this block of code to create the new options for drop-down list 2:

For Each strValue in arrValues
    Set objOption = Document.createElement("OPTION")
    objOption.Text = strValue
    objOption.Value = strValue  
    DynamicOptions.Add(objOption)
Next

What we’ve done here is set up a For Each loop to loop through all the items in the array arrValues. For each of those items we create an instance of the Option object; this object represents an individual option in a drop-down list. For each instance of the Option object we then assign the value of the array item to both the Text and Value properties:

objOption.Text = strValue
objOption.Value = strValue

In other words, if the first value in our array is A we create a drop-down list option that not only has the label (Text) A but has the same value as well. We then use the Add method to add this new option to drop-down list 2:

DynamicOptions.Add(objOption)

And then we loop around and repeat this process until all the items in the array arrValues have been configured as drop-down list options. Once that’s finished we are done.

And not a moment too soon. Do you realize that, as we write this column, it’s not even 10:00 AM yet? This is going to be a long day.

Incidentally, for those of you who haven’t seen The Simpsons Movie yet, the Scripting Guy who writes this column found it refreshingly-good. There’s no doubt that the Simpsons glory days are behind them (no; why would a statement like that make anyone think of the Scripting Guys?); nevertheless, the movie had some pretty entertaining parts to it. For example, the Scripting Guy who writes this column has spent most of this morning singing the Spider-Pig song:

Spider-Pig, Spider-Pig
Does whatever a Spider-Pig does.
Can he swing from a web?
No, he can’t; he’s a pig.
Look out: here comes the Spider-Pig.

Trust us: that’s a good song.

Or at least it is at 2:00 in the morning.