Script Triggers: Filter as You Type
For years, FileMaker developers have been devising various filter techniques. The idea is that you type all or part of a name, part number, description, etc… and a list of results filters down to show relevant matches. As handy as these techniques are, they always stop just short of perfect because, before FileMaker 10, you had to exit the field before the filter would take effect. Using FileMaker 10’s powerful Script Triggers, you can make the impact of your filtering more immediate.
Note: We’ve never done this before, but the idea, scripts, and sample file for this technique come directly from FileMaker luminary and Six Fried Rice reader David Graham of Bit Tailor. We’re publishing it here (with David’s permission) because it is an excellent example of Script Triggers solving an age-old problem in an elegant way.
There are as many ways to filter lists in FileMaker as there are developers implementing it. The beauty of this technique is that it doesn’t matter if you prefer exploded keys and filtered portals, aggregate text fields and a find, or (my personal favorite) scripted multi-request finds. Whatever you want, when it is fast, clean filtering you’re after, it is always better if the results appear as you type. This sort of thing was essentially impossible with FileMaker 9. Once a user started entering data in a field, you were hands-off until they finished.
Some people dreamed up horrifying solutions with looping scripts and all manner of wackiness. These techniques, in my opinion, never worked well. Consequently, we were always resigned to the “press Enter when you’re done” model. But when the results appear as you type, the user gets immediate feedback, only needs to go as far as necessary to get the result she wants, and doesn’t have to click back into the field to correct or make a change. So it is clearly a better model. See for yourself:
David’s technique relies on the handy OnObjectModify trigger on the filter field to kick off a script every time the field changes. This includes:
- When you add a single letter to the field by typing a key.
- When you remove something by pressing Delete or Backspace.
- When you cut text form the field or paste it in.
You may be tempted to use the OnObjectKeystroke trigger for something like this, but OnObjectModify gets you more bang for the buck: It handles cut and paste, and doesn’t require all the complexity of keystroke triggers.
The Code
I’ll let you explore David’s sample file for the full scoop, but the core of his technique can be found in two places. First, he uses an exploded key filtering technique, which I won’t cover her, except to say that the idea is to process some text data and produce a multi-line key that includes partial match values. In other words, if the value is “Test” then the key would match “T”, “Te”, “Tes” and “Test.” In this way, you can type all-or-part of the value and see the results. Look at David’s ExplodeToMultikey custom function to see how he accomplishes this.
If you prefer, you can use scripted finds and a list view layout to do your filtering instead.
But the interesting part is this very simple trigger script:
Set Variable [$currentObject; Get ( ActiveLayoutObjectName )]
Commit Records/Requests []
Go to Object [ $currentObject ]
Set Selection [ Start: Length (Get(ActiveFieldContents)) + 1]
That’s it. This script really just does two things:
- It commits the record, causing anything you’ve typed in the filter field to take effect.
- It returns you to the field, so if you type again, your keystrokes will go right on the end of the field.
In this way, as you type, your changes reflect immediately. Very cool.
Note: If you were using finds instead of exploded keys, you would add a a few more steps to your script to switch to Find mode, build a find request or two, and then perform the find.
You can download the working file right here.
Thanks to David for the great technique!
Using OnModeEnter Script Triggers to Display Custom Find Layouts
Script triggers have in many ways completely changed the game when it comes to Filemaker development. The fact that I can launch script triggers on mode changes opens up a whole slew of possibilities, one of which is being able to have a huge amount of control over where my users end up and what information they see while they are navigating my system. If I want to make sure that my users always have fields X, Y and Z regardless of how they get to find mode, I now have a way to make that happen.
The Old Way
Pre-10, it was a little bit of a hassle to try to give users a customized find layout. For starters, it required scripting a method that would take the user to the correct find layout for their current context, making that process available on the main layout itself via a button and then locking down the permissions and changing the menu commands so that the users could only get to find mode via said button. It was doable, but kind of a headache. Now with script triggers, I can simply set a script to run when the user enters find mode that navigates them directly to the custom find layout I’ve built for them, and no matter how they get to find mode they will always end up looking at what I want them too.
How It Works
The process of setting this up is pretty simple in and of itself. Let’s take a look at our starting point:

There is a pretty good amount of information being laid out for my users on this particular screen. Really they only ever search in about eight of these fields. The rest is just clutter when it comes to finds. So, I want to give them only what they need to see when they run a find.
To do that, I need to take three steps. The first step is to design my find layout, including only the fields that are essential for my users to find the data they need. Once I’ve got that done, I need to write a script to navigate to that layout. This can be a complex navigation script that tracks a history of visited layouts or a simple go to layout script step. Once I’ve got my script ready, I need to set the correct script trigger to make it run. The script trigger I’m interested in for this is called OnModeEnter, and you set it on the main detail layout that the users see (the one in the picture above for me). You can get to the layout script triggers on the last tab on the right in the Layout Setup dialog box. The OnModeEnter trigger runs whenever the modes you have selected are entered. So, to make sure that the user ends up on my find layout only when they are entering find mode and not at any other point, I deselect the “Browse” and “Preview” options. Now, this trigger will only run when the layout I’m on enters find mode, no matter how find mode is entered. So at this point, when my users try to search for an order they start at the screen above and are immidiately shuttled to the much more find friendly screen below:
Now my users are happy that they have a simple find screen to look at without all the exta clutter, and I no longer have to try to lock down my system of all it’s innate functionality to keep my users where I want them.
Note: There is actually one final note to make all of this work seemlessly. Since you’ve taken your users away from the main detail page to set the find criteria, you should probably take them back once they actually preform the find. To do this, you’ll need to write one more script to navigate them back to the main detail page and set it with the OnModeEnter script trigger on the find layout to run when browse mode is entered. This will make sure that your users are taken back to the details page to view their results.
Phoenix FMPug: Presenting FileMaker 10
Just a quick announcement for those of you in the Phoenix area. I’ll be presenting FileMaker Pro 10 with a focus on practical uses for Script Triggers at the next Phoenix FMPug meeting. We’d love to see you there.
Update 10-Jan-2009: I added a link to the RSVP form.
- When: January 20th, 2009 at 6:30 PM to 8:30 PM
- Where: The Burton Barr Central Library, 1221 N. Central Ave (just South of McDowell on Central)
- Who: Anybody interested in learning, sharing, and meeting about FileMaker Pro
If you plan on attending, please rsvp here so they organizers can get a proper count.
The Phoenix branch of FMPug, the FileMaker Pro Users Group, is young and growing. This meeting promises to be a hit, with all the FileMaker 10 excitement. We’d especially like to thank Audrey Akhavan from FM Magic, Inc, for starting the group and inviting us to present. Thanks, Audrey!
We can’t wait to see you all there.
Now back to regularly scheduled programming.
Script Triggers: Using Layout Triggers for a Dynamic Tab Orders
If you’re a male, do you really need to be asked you if you’re pregnant when you are at a clinic? If your female, do you need a prostate exam? Probably not. There are little nuances to data entry that occur with just about every solution that make it just slightly more tedious to collect information with just a standard tab order. We’re going to remedy that with using a simple layout keystroke trigger.
Dynamic Tab Order for FileMaker 10
In FileMaker there is only one way to navigate the tab order. This can be annoying to an end user who has to tab through a bunch of useless fields to get to the good stuff. The gender question above is a perfect problem to solve using a dynamic tab order in FileMaker 10.
Note: As Mikhail Edoshin points out, this process could be accomplished by attaching a script trigger directly to the field in question. The reason I chose to attach the trigger to the layout is so all tab order changes are centralized in one script. For instance if you had 4 or 5 different modifications to the tab order, you would still only have one script when using the layout trigger. If you were to place a trigger on each individual field you would need 4 or 5 scripts. That was really the main idea of this whole post but I left it out for some stupid reason.
Thanks for the heads up Mikhail.
A better way for our tab order to progress in our example is to just skip fields depending on which gender is choosen. Here is the psuedocode for what I think the tab order should look like:
IF the active field is Gender THEN
IF Gender = Male THEN go to the prostate question END
IF Gender = Female THEN go to the pregnancy question END
END
Finding our Key
The TAB, ENTER and RETURN as they are the three keys that filemaker uses to move to the next field.
Note: You can specify one, two, three of these keys to progress to the
next field in the Format >> Field/Control >> Behavior...
So using our knowledge from the previous article about keystroke triggers and consulting our ascii tables we know the following will return true if any one of those keys is pressed:
Let(
keyCode = Code( Get ( TriggerKeystroke ) );
keyCode = 9 or //Tab Key
keyCode = 10 or // Enter
keyCode = 13 // Retun
)
Overriding the tab order
Assuming that my table name is TEST and my field names are GENDER, PROSTATE_EXAM? and PREGNANT, we can write our script.
If[ Let( keyCode = Code( Get ( TriggerKeystroke ) ); keyCode = 9 or keyCode = 10 or keyCode = 13) ]
If[Get( ActiveFieldTableName ) & "::" & Get( ActiveFieldName ) = getFieldName( TEST::GENDER )]
If[ TEST::GENDER = "F"]
Go to Field [ TEST::PREGNANT? ]
Exit Script [Result: False]
Else If [ TEST::GENDER = "M" ]
Go to Field [ TEST::PROSTATE_EXAM? ]
Exit Script [Result: False]
End
End
End
Notice on the second line of the script we combined two get functions to determine the table and name of the field and then compared that to the result of getFieldName( TEST::GENDER ):
Get( ActiveFieldTableName ) & "::" & Get( ActiveFieldName ) =
getFieldName( TEST::GENDER )
The reason we do this is to make sure that if for some reason you ever decide to change the name of either the table or field the script won’t break.
You’ll also noticed that I use the step Exit Script [Result: False] after I navigate to each field. The purpose of this step is to reject the TAB, ENTER or RETURN key press. If we were to leave the Exit Script step out, FileMaker would process the keystroke and therefore go the the next field in the tab order after the field I just told it to go to. This would drive everyone crazy!
Once I’ve played with this technique a little more I’m sure it will prove quite useful. It definitely makes data entry a little more user friendly.
Isolate Any Record, Anywhere, Anytime and Any Context With One Script
There are some things that are easier to explain through examples. Putting the Set Field By Name script step to work is definitely one of them. It’s not a complicated process, but seeing the new Indirection capabilities that Filemaker 10 has to offer makes a much stronger impression than trying to talk through it. Also, all my introductory quips for “isolating” and “isolation” were turning out quite depressing. So, here is how we used to find a specific record, and how we can do it now.
The Old Way
For this article I’m going to assume you are using two methods that are a part of our development process. The first is multiple parameter passing (feel free to check this out if you’ve never run into it before) and the second is Safe Find. Safe Find is a script we use to safely run a find and capture any errors that occur and return them without throwing an error dialog. Here is a copy of the actual script:
So, now on to the concept of Indirection. Here is how we used to find customers using our standard naming conventions, parameter passing and error handling:
Now, here is how we find orders:
And now for something completely different. Here is how we find vendors:
By now you’re probably seeing a trend in our scripting that has driven me nuts since day one. In Filemaker 9, we had to maintain a separate set of scripts for each context that we wanted to operate in. If we want to find a Vendor, that’s one script. Find an Order? That’s a second script. Customer? A Third script.
The New Way
Here is how we can find a Customer, Order or Vendor now:
This little beauty does something that makes us here at Six Fried Rice absolutely giddy. I can call it from any layout, pass it an ID and it will isolate the record with the corresponding ID without any further hassle! It is completely context independent. Essentially we now have a single script to replace every find by ID script we have ever created. A huge part of development model revolves around using structures, systems and conventions to centralize and simplify the development process. This particular script is a perfect example of a very simple application of a very useful feature to cut out a huge amount of redundancy in a systems.
Note: This script does require that a few things are in place before hand. For one, you’ll notice that we use the Set Field By Name to set “ID” to the parameter that is passed in. This only works if you strictly follow the naming convention that dictates having a primary key field called “ID” in every table. I’ll be posting an article going much deeper into our own conventions, but for now remember that to use a script like this, you must have consistent naming conventions throughout your system or the script will not execute correctly.





