Hey, Scripting Guy! Question

Hey, Scripting Guy! I’d like to create an HTA that, upon loading, can open a text file and then display the contents. However, I’d like a particular keyword in those contents to be highlighted. How can I do that?

-- GD

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GD. You know, a lot of people at Microsoft pooh-pooh the work that the Scripting Guys do. “Take that Hey, Scripting Guy! column,” they’ll say. “Big deal. I bet a 4-year-old could write a column that good.” Well, we’d just like to say that those people are wrong. As it turns out, a 4-year-old could write a better column.

Yesterday the Scripting Son had his wisdom teeth removed. (But don’t worry; he didn’t have all that much wisdom to lose in the first place.) In turn, the Scripting Dad had to stop at the pharmacy on his way home to pick up a prescription. While waiting his turn at the counter he ran into the wife and 4-year-old daughter of a guy he used to coach with. As it turned out, the wife and daughter had walked to the drugstore, about a mile or so from their house.

The Scripting Guy and the Coach’s Wife chatted for a moment, with the Coach’s Wife noting that her daughter didn’t really enjoy the walk. “It’s such a nice day I thought a walk would be fun,” said the wife. “But the little one doesn’t seem to agree with me. She kept saying it was too far to walk.”

It was at that very moment that the little one spoke up. “Mommy, can Coach Greg give us a ride home?” she asked. “My legs are bored.”

My legs are bored! The Scripting Guys would kill to be able to write something that good.

Note. That is just a figure of speech, right? I mean, the Scripting Guys wouldn’t really kill just to be able to write a cute phrase, would they? Would they? Hello?

Oh, well; that’s not the first time we’ve been bested by a 4-year-old. We’ll go ahead and answer your question, GD. It won’t be anywhere near as cute and clever as “My legs are bored.” However, it will have a little more scripting code:

<Script Language="VBScript">
    Sub Window_Onload
        Const ForReading = 1

        Set objFSO = CreateObject("Scripting.FileSystemObject")
        Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt")

        strContent = objFile.ReadAll
        objFile.Close

        strNewText = "<span style='background-color: #FFFF00'>text</span>"
        strContent = Replace(strContent, "text", strNewText)
        DataArea.InnerHTML = strContent
    End Sub
</script>

<body>
    <span id = "DataArea"></span>
</body>

As you can see, we have a very simple HTA here. (If you don’t know what HTAs are, then take a look at our HTA Developers Zone.) This simple HTA consists of two parts: the <BODY> tag and a single subroutine (enclosed, as all good subroutines are, inside the <SCRIPT> tag). It goes without saying that there’s not much to the <BODY> tag; in fact, all we have there is a <SPAN> named DataArea:

<span id = "DataArea"></span>

If you’re new to HTML tagging, a <SPAN> is simply a named area of an HTML file (or an HTA file). By setting aside a portion of the document and giving it a name, we can refer to – and modify – that section of the document using a little scripting code. It should come as no surprise, then, that this is exactly what our subroutine is going to do.

Speaking of our subroutine, you might have noticed that we gave it the name Window_Onload. That’s not a name we picked because it was, say, our grandfather’s name. (In case you’re wondering, no, it wasn’t.) Instead, any subroutine that has the name Window_Onload automatically runs each time the HTA is loaded or refreshed. GD needs an HTA that, on its own initiative, goes ahead and opens a text file each time it gets started. How do we do that? We just put the file-opening code into a subroutine named Window_Onload.

Which, now that we think about it, is exactly what we did. We’d like to see a 4-year-old do that!

Inside our subroutine we start out by defining a constant named ForReading and setting the value to 1; as the name implies, we’ll use this constant when we go to open, and read, the text file. We then use these two lines of code to create an instance of the Scripting.FileSystemObject object and open the file C:\Scripts\Test.txt for reading:

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt")

As soon as the file is open we use the ReadAll method to read in the entire file and store the contents in a variable named strContent:

strContent = objFile.ReadAll

And then once we have the contents safely stashed away in memory we go ahead and close the file:

objFile.Close

That part was pretty easy, wasn’t it? And don’t worry: it doesn’t get much harder, either.

We’re assuming that our text file looks something like this:

Here is some sample text taken from the file C:\Scripts\Test.txt. The idea is to take this text 
and then highlight each instance of the word text. Like this one: text.

If we wanted to, we could simply set the InnerHTML property of our <SPAN> to the value of strContent; that would result in the contents of the text file being displayed in our HTA. But that’s something a 4-year-old would do. A 74- -- um, we mean a 24-year-old, like the Scripting Guy who writes this column, would go one step further: he would highlight a target word anywhere it appeared in the text. How’s he going to do that? We’re just about to show you.

The InnerHTML property is a very cool property. Why? Because it not only allows you to assign text to a <SPAN> but it also allows you to assign HTML formatting to a <SPAN>. If you want to highlight a single word using HTML tags, one way to do that is to turn that single word into a sort of mini-<SPAN>, then assign that mini-<SPAN> its own background color. For example, suppose we wanted to highlight the word text. In that case, we could use HTML tagging similar to this:

<span style='background-color: #FFFF00'>text</span>

And guess what? That’s exactly what we’re going to do. For starters, we take the preceding HTML tagging and assign it to a variable named strNewText:

strNewText = "<span style='background-color: #FFFF00'>text</span>"

We then use this line of code and the Replace function to search through the value of strContent and replace all instances of the word text with our HTML tagging (which simply displays the word text on a yellow background):

strContent = Replace(strContent, "text", strNewText)

That makes the value of strContent equal to this:

Here is some sample <span style='background-color: #FFFF00'>text</span> taken from the file C:\Scripts\Test.txt. 
The idea is to take this <spanstyle='background-color: #FFFF00'>text</span> and then highlight each instance of the word 
<span style='background-color: #FFFF00'>text</span>. Like this one: <span style='background-color: #FFFF00'>text</span>.

Now we can go ahead and assign the value of strContent to the InnerHTML property:

DataArea.InnerHTML = strContent

Lo and behold, not only does our HTA display the contents of the file C:\Scripts\Test.txt, but every instance of the target word is highlighted:

HTA


Is that cool or what?

We hope that answers your question, GD. Now we just need a socko-boffo ending for today’s column, something along the lines of, “Can we go now? My legs are bored.” Hmmm ….

What’s that? You say you have a suggestion: “Can we go now? Your readers are bored.” Oh, man; that was uncalled for!

On the other hand, we can’t really think of anything better, so we’ll go with that. See you all Monday.