Tutorial details:
Written by: Flashjunki
Difficulty Level: Intermediate
Requirements: Flash 4
Download FLA
Active Search List  (version 2 : April, 2000) Now also includes tutorial for the workings of the filtering list script.
Further notes on my variables, what they are for, and how to deal with that nagging "200,000 calculation limit in one action list" problem are included inside the "FLA". No-- I know not everyone has encountered this problem unless they have programmed an infinite loop but I hit this problem frequently. : )



Actual Flash code shown in red.


Introduction
This is a partial tutorial. I will cover the logic behind the working of the filtering list. If you are familiar with Flash the rest of the workings of this project will be relatively easy to grasp. There is a "SORT" button -- I have the alphabetical sort routine as a separate tutorial. It is only several lines of code in one frame. BUT it is one of my worst 200,000 calculation limit offenders. I believe that with two variables (the button name and the URL it links to) being sorted at a time you will find it crashes at around 90 items. That is why it is a separate option. To enable it permanently, simply delete the "SORT" button and set the variable "alphabetize" that is in frame 1 of the main timeline to "1".

On with the filtering links list. To start, you will find there are many embedded movie clips. This is necessary. To begin, the entire project is only one movie clip. Not only does this leave the project tidy and easier to copy and paste into other projects, but it also allows it to be a draggable object, which it is.

Inside this complete movie clip, you will find several objects. The only one of importance is the "weblinks" object. This contains both the interface that allows the user to type into and also the "scrolltarget". Just like we needed a separate object to enable "dragging", we need a separate object to "scroll". Inside the "scroll" object, we find an object called "allbuttons", which is a container to hold all the buttons. (There is only one button until the script runs and starts duplicating them). Now let's look at the button itself. This is where all the code is that makes the whole effect work. There are 5 frames. Only three have any real code in them. Frame 4 is just a loop and Frame 5 is a "call" routine for converting to lowercase both the variables and also the user input for purpose of ignoring case sensitivity. Since this also may cause too many calculations at some point -- or because some people may want to disable the case insensitivity... it is also an option. There is a variable on the main timeline. Set it to either 0 or 1 depending if you want to be able to type "OnLiNe" and have it find "online" and "Online" as correct results or not. Frame 1: Initial Setup
In this frame we duplicate the buttons and set the text in them for the initial list. This is the only time we run this frame -- for the initial setup. (It also gets called again if you hit the "SORT" button in this demo, or if we ever need to reset the list completely... for instance, if the user deletes his input entirely.)
Comment: ----------------------------------------------
 Comment: hide original button object
 Comment: ----------------------------------------------

Here, we get rid of the initial object. It is not used except for creating duplicates.
Set Property ("button", X Position) = -1000
 Comment: ----------------------------------------------
 Comment: Show ALL Links
 Comment: ----------------------------------------------
 Set Variable: "q" = 0

Now we start counting from 1 to (the number of buttons we will have)...
Loop While (q</:total)
 Set Variable: "q" = q+1

Set up a name for our new duplicate button "dup" equals "button1, button2, button3..." up to "q"
Set Variable: "dup" = "button"&q
 Duplicate Movie Clip ("button", dup, q)

Here we set the "y" position of the new button. Since the button is placed correctly to begin with, I position new duplicates at (the place of the original one, PLUS the number of the button (1, 2, 3,... etc) times a variable I called "/:button_spacing". It helps to name things that you can remember what they are for months later when you are trying to change your code. Or, as in this case, if it's someone different entirely who is trying to read the code than the person who wrote it. People will thank you for being clear. Yourself included.
Set Property (dup, Y Position) = (q-1)*/:button_spacing

Just in case, I also set a variable for left indent. I have no real use for this variable so it's set to zero. But just in case and to make the reading of the code clearer, it is a variable with a name.
Set Property (dup, X Position) = /:indent

There is a text box on each button called "linkname". Initially it is blank. Here I fill it with the text from the variable definitions on frame 1 of the main timeline. That is where all the buttons names and URL links live. Since the variable lives on the main timeline I can refer to it with a "/:"
Set Variable: dup&":linkname" = Eval("/:text"&q)
 Set Variable: dup&":link" = Eval("/:link"&q)

Because there is no way in Flash 4 to set the color of text, and I wanted two colors of text (one for mouseover and one for regular display) I created two movie clips with different colored text boxes in them. They contain exactly the same text.  Just one has a different color. For the "mouse Over" text I called the movie clip "over".
Set Property ("button"&q&"/over", Visibility) = false
 End Loop

The scrollbar is only visible of there are enough links to require scrolling. But, in case we ever need to reset the list, and the scrollbar was set to "not visible"  we reset it here.
Set Property ("../../../scrollbar", Visibility) = true

The variable text box ":active links" is just a display so the user can see how many links are in the current list (after filtering). Since we haven't filtered yet, and we want the list to have an initial value, we set it here. 
Set Variable: "../../../:active_links" = /:total&" link(s) in list."
 Set Variable: "/:active_links" = /:total

Frame 2: Filter the List
NOTE: This frame does NOTHING first time around.

This is where the link filtering happens. This is the only frame in this entire project that is really unique and that I can take credit for. Although to be honest, I got the idea from Microsoft's "Help" index system, where this same effect happens. I liked it. I wanted one. So I made one. There are no really original ideas are there? Just new implementations of old ones.

the LOGIC:
Here is where I sat down with pencil and paper and pre-thought out exactly what I wanted the script to do in order to perform the filtering list. In many cases, I highly recommend sitting down with pencil and paper BEFORE touching the computer. You will end up saving yourself a LOT of time. It also helps to break large problems into the smallest possible pieces. The individual components of how this works were easy to solve. When I first though "Hey this is what I want to do..." the overall project was to complex for me to solve all at once. So here are the individual components I broke the problem down to to be more easily programmed:

I decided:

(a) when the user types, I need to keep track of what he types live.
(b) as soon as it changes (not all the time -- to save on CPU processing -- no use continually running this code -- ) start checking.
(c) checking involves the following: comparing the amount of characters that have already been typed (say there are five) in five character chunks against the items in the list.
(d) if a match is found, add that item AND ITS LINK to the new list.
(e) I immediately decided I wanted this to work in a non-case sensitive manner.

Easy, right?

So there are a number of loops going on.
(a) a continuous loop to check user input.
(b) if typing has occurred, a loop to start checking items one at a time
(c) in each item, checking the text (one)* character at a time.

*NOTE: You are not really checking one character at a time. You are checking (user input length) characters at a time. Because it's relatively pointless to check for one character at a time... (say the user types "e") -- the most common character in the English language... well... pretty much every link is still going to be in your list. There's not much point in that... plus it uses a lot of processor power. The longer their input the less checking is required. SO I set a minimum amount of characters to be checked. (currently 3). If the user hasn't typed at least (3) characters nothing is checked.

VERY IMPORTANT NOTE: I have gone to extensive lengths in much of my scripting to avoid the 200,000 calculation limit that Flash has. However, in this links list there really is no way to avoid it. After you have a certain amount of links, this filtering links list will generate a huge amount of calculations. It does already. I have not seen the problem personally on this project but I know it will happen for someone out there. There are a few things you can do to solve this problem. One of them is raising the minimum input requirement before the list starts searching. The higher you set it, the fewer calculations this script will produce. Even raising it from 3 to 4 will significantly reduce calculations.

Comment: EXPLANATION of code: This one isn't as complicated as it looks. To start, convert use input to lowercase. Fame 2 checks if the user has typed anything more or less than the last time we checked.... if so, control is passed to frame 1. First, we clear the list. Then, Remember, it is LIVE updated. The variable is constantly changing as the user types. (Trace) it to see. Check all imported link descriptions (from 1 to "/:total") for being at least 3 characters long (no point searching for 1 or 2 character words) Search the text description "/:text"&n from the first letter to the last (minus length of "findit") for the character string "findit". If it is found, then add it to the list via duplicate movie clip. Simple - right?


In this release of the Active Search List I have included a variable on the main timeline as an option to be case sensitive or not. This, again, may or may not be useful to your users, I cannot offhand think of a case where you would WANT the list to be case sensitive. But it would reduce a monstrous amount of calculations to do so. This is one more option you can disable if your list is long enough that it DOES exceed the 200,000 calculation limit. That is the only reason I have set it as a separate variable.
If (not(/:case_sensitive))
 Comment: ----------------------------------------------
 Comment: convert entry to lower case
 Comment: ----------------------------------------------
 Set Variable: "input" = findit
 Call ("convert_to_lowercase")
 Set Variable: "findit" = output
 End If

You will find the fifth frame is the one titled "convert_to_lowercase". Once again, it helps to name things that make sense. There are a number of tutorials on the net that deal with this topic to varying degrees of competency so I will not cover them here. Just accept that it works -- it does.  : ) 
Comment: ----------------------------------------------
 Comment: initialize counters
 Comment: ----------------------------------------------
 Set Variable: "m" = 0
 Set Variable: "n" = 0
 Set Variable: "p" = 0

We need three counters. Remember I mentioned there were three loops going on: One to keep detecting new user input (this is done via a "Frame" go to action. Another loop to count through the list of links. And another to step through the characters in each link. The last variable you see here "p" is used as a counter to count how many items match our user's input. 
Comment: ----------------------------------------------
 Comment: start counting (up to total links)
 Comment: ----------------------------------------------
 Loop While (n</:total)
 Set Variable: "n" = n+1

'n' is our counter to keep track of which link we are on. We only cycle through 'n' one time. In other words, n counts from 1 up to the total amount of links in the list, then we're done. 
Comment: ----------------------------------------------
 Comment: wait for enough characters
 Comment: ----------------------------------------------
 If (Length(findit)>=/:minimum_search)
 Set Variable: "text" = Eval("/:text"&n)

Here we wait for the user input to be at least "minimum_search" characters long. (The reasons for this were stated above.) 
We have to check to see if we need to convert the links list entry to lowercase just like we checked above to see if we needed to convert the user's input to lower case. 
If (not(/:case_sensitive))
 Comment: ----------------------------------------------
 Comment: convert our search list to l.c.
 Comment: ----------------------------------------------
 Set Variable: "input" = text
 Call ("convert_to_lowercase")
 Set Variable: "text" = output
 End If

Now we start checking the text itself. But there's no point in checking the text if the text in our link is shorter than what the user has typed in. In that case there's no possible way it could be a match, so we skip it right away... 
If (Length(findit)<=Length(text))

'm' counts from the leftmost character in the link text all the way to the right... MINUS the length of the search string...

SAMPLE:
text='Microsoft's Online Web Site'
user input="online"
Searches from "M" through to the "b" on the word "Web".

After that point, there's no way the search string could match so we save ourselves precious calculations by stopping searching that link text at that point.
Set Variable: "m" = 0
 Loop While (m<=(Length(text)-Length(findit)))
 Set Variable: "m" = m+1
 If (Substring (text,m,Length(findit)) eq findit)

However, as soon as we have a match we stop checking that link. (In the case of the above sample, that would happen after only 13 comparisons...)
Since we have a match, we can now add this link to the new list. (We cleared the list to prepare for the new list already... that happens in the next frame, where we check for user input... so we can now start duplicating new buttons again... exactly the same code as the previous frame...)
Set Variable: "p" = p+1
 Set Variable: "dup" = "button"&p
 Duplicate Movie Clip ("button", dup, p)
 Set Property (dup, Y Position) = p*/:button_spacing
 Set Property (dup, X Position) = /:indent
 Set Variable: dup&":linkname" = Eval("/:text"&n)
 Set Variable: dup&":link" = Eval("/:link"&n)
 Set Property (dup&"/over", Visibility) = false
 End If

Once all the loop checking is done, we update the amount of found links. Since the variable "p" was ONLY increased if we foud a match, 'p' is the amount of links found in the list matching the user's input.
Set Variable: "../../../:active_links" = p&" link(s) in list."
 Set Variable: "/:active_links" = p
 If (p</:list_height)
 Set Property ("../../../scrollbar", Visibility) = false
 End If
 End Loop
 End If
 End If
 End Loop

Frame 3: Wait for User Input
Here we check to see if the user has changed what s/he typed since the last time we checked. If the have, we clear the list (by removing all the duplicate buttons--except the original one). We also set the position of the scrolltarget (the single object which is a movieclip containing ALL the buttons, whether they are duplicated or not.) We set it back to 0. We do this because... say you shows ALL links. Then you scrolled way down to the bottom of that list. Now you start typing and filter the links down to only two or three. They will be way above your viewing area... way up off the top somewhere and you will get a blank list. You'd have to scroll way up to see them. To work around this I simply reset the scroll to the very top item each time the user types anything.Comment:
----------------------------------------------
 Comment: frames 3&4 loop
 Comment: until you type or delete
 Comment: ----------------------------------------------
 If ((findit ne oldsearch) and Length(findit)>=/:minimum_search)


This only runs if we have more than (minimum allowed) characters. Otherwise... (see below) we simply show the entire list.
Comment: ----------------------------------------------
 Comment: process typing/deleting (more than (minimum_search) characters
 Comment: ----------------------------------------------
 Comment: Clear the List First
 Set Variable: "q" = 0
 Loop While (q</:total)
 Set Variable: "q" = q+1
 Remove Movie Clip ("button"&q)
 End Loop
 Set Property ("../../scrolltarget2", Y Position) = /:smin


We go to Frame 2, the filtering script, and see if the new input (whether more or less than the previous input) has any matches. This way it doesn't matter if you are typing or deleting it will work either way.
Go to and Play (2)
 Else
 Comment: ----------------------------------------------
 Comment: process deleting to less than (minimum_search) characters
 Comment: ----------------------------------------------

We show the entire list by going back to Frame 1, where we initially set up the entire list.
If ((findit ne oldsearch))
 Go to and Play (1)
 End If
 End If
 Set Variable: "oldsearch" = findit


Frame 4: Active_Search or Manual Press Button?

Here we check if "active_search" is set to 1. If not, we don't do anything at all. Look at the actions in the button that says "GO". Yuo will find it tells this timeline to start playing again in Frame 2 -- the filtering script. That's all there is to it.

If (/:active_search)
 Go to and Play (3)
 Else
 Stop
 End If

Since this seems to be one of my most popular Flash Toys and it was also one of my original ones -- it was not a very easy to read piece of code nor was it very well documented. As a result I have had numerous emails asking for explanations... I hope to cut those down by offering this semi-tutorial, which covers most of the tricky parts of this routine. I also put some effort into making the code cleaner and more easily understandable by using variable names that make clear sense.

Enjoy.

: )

by: