Auto-indexing User Text Entry
September 12, 1999
by Pat McClellan
Dear Multimedia Handyman,
I have some problems regarding programming a children's dictionary. I'll have all of the words in a field, and I want to create dynamic input so if the user types "appl", the dictionary matches the first few letters and shows the word "apple". It's giving me a headache trying to figure it out, appreciate any help.
Alvin Gan
Dear Alvin,
Since this is a children's dictionary, you're probably OK storing the words in a field. (For a larger project, I'd recommend using a database xtra.) Storing the words in a field is an easy way to add and delete the words, but when we get down to processing it, you'll want to move the words from the field into a list. There are several list operations that are perfectly suited to our needs.
It's fairly easy to convert a field into a list, but that process kind of depends on how you format the string in the field. If your words are entered into field "wordlist" so that it looks like a list...
["apartment", "apple", "apricot", "appreciate"]
... then you can convert it to a list like this:
myList = value(field "wordlist")
It's more likely that you'll want to build your list of words without having to worry about all the quote marks and adherance to list syntax. So, if your field looks like this instead...
apartment apple apricot appreciate
... you'll need to use a utility handler to build your list. This will do the trick:
on buildList fieldName global gMyList gMyList = [] textString = field fieldName set the itemDelimiter = RETURN lineCount = the number of lines in textString repeat with whichLine = 1 to lineCount add gMyList, line whichline of field fieldname end repeat sort gMyList end
This handler takes all of the words in the field and adds them to a list, stored in the global variable gMyList. Note that the last line sorts the list alphabetically, which means that you really don't have to worry too much about entering the words in alphabetical order. Sorting has another very valuable function in a list. It makes it extremely fast to search through.
Here's a demo which uses the features we want to achieve. I'd suggest entering some words into it right away. Might as well use the ones I've mentioned: apple, appreciate, apricot, apartment. Note that you don't have to worry about alphabetical order. The list sort takes care of that.
Download a sample movie in Mac or PC Format.
Another key list function is one called findPosNear(list, value). This command requires that you provide the list name, and a value to check. So, if we test it on gMyList...
put findPosNear(gMyList, "apricot") --3
... it returns the integer position in the list occupied by "apricot". You could actually do that same thing with getPos(), but findPosNear does something a little more sophisticated. Try this:
put findPosNear(gMyList, "ap") --1 put findPosNear(gMyList, "app") --2 put findPosNear(gMyList, "appr") --3
What we're seeing is that each incremental letter that we add to the text string changes the position in the list. That's the behavior we're looking for. What we need is the actual word at that position of the list, so it's pretty easy to retrieve that. One thing to note about findPosNear, try this:
put findPosNear(gMyList, "b") --5
When the test string is greater than the last item in the list, it will return a number that is 1 more than the count of your list. If you try to do a getAt function on the list with this number, you'll get an error message. So, we'll have to make sure that we allow for that possiblity.
The only other thing we've got to figure out is how to run that findPosNear check after each letter is entered. For that, we're write an autoIndex behavior. This behavior will need to run that findPosNear check every time a new letter is added to the field. Luckily, there's an event that triggers on keyUp, so we'll put all of the findPosNear stuff there.
-- autoIndex behavior -- copyright © 1999, ZZP Online, LLC -- free use for Director Online readers global gMyList property pMyMem, pResultField on beginSprite me pMyMem = sprite(me.spriteNum).member end beginSprite on keyUp me input = pMyMem.text index = findPosNear(gMyList, input) if index > gMyList.count then nearestWord = "not available" else nearestWord = gMyList[findPosNear(gMyList,input)] end if if nearestWord contains input then pResultField.color = rgb(0,0,0) pResultField.text = nearestWord else pResultField.color = rgb(128,128,128) end if end keyUp on getPropertyDescriptionList me set pdlist to [:] addprop pdlist, #pResultField, [#comment:¬ "Result display field:", #format:#field, #default:1] return pdlist end getPropertyDescriptionList
I added a little flourish of color effect to the output field. If the input is not contained within any of the words in our list, then the color of the result field is changed to gray. It a nice effect I think.
Good luck with your program.
Copyright 1997-2025, Director Online. Article content copyright by respective authors.