Six Fried Rice Methodology Part 2 – Anchor Buoy and Data Structures
In the last post about the Six Fried Rice methodology I went over the concept of data separation and why we use it. That is essentially the starting point for how we structure the files of our system. One file contains all of the UI components and scripts for the system while a second file contains all of the actual data. Just doing that one basic separation provides several benefits that generally make life easier, but how we structure the data within the Base File itself is equally if not more important than the data separation.
To begin with I’m going to go over how we initially setup our tables. The first thing we do after we create a table is add a number field named ID that is unmodifiable and set to auto-enter a serial number. This may seem obvious to a lot of people, but as an absolute beginner I never even thought about this approach. For simplicity’s sake we never call our primary ID field anything but ID. If we ever need to store another table’s ID for relationship purposes, we use the convention ID_ORDER or ID_PURCHASE_ORDER_LINE. Naming things according to a set standard of prefixes makes organizing and locating our fields a little bit easier and saves us from a lot of hunting through long lists of names. Typically we apply this to all fields that can logically be grouped together. For example, it we have two date fields and two purchase order fields in a table, here is what our field list would look like:
- DATE_ESTIMATED_SHIP
- DATE_PROMISED
- ID
- ID_PO
- PO_VENDOR_NAME
- PO_CREATED_BY
Standards like this help us keep our fields consistent, and should I ever need to work on a table that Jesse has created I will know exactly what I’m looking at. Logically grouping your fields and giving them a standard naming convention will make navigating your data structures considerably easier.
Come to think of it, most of what our conventions are about is legibility. The simpler and more standardized you can make your systems the easier it is to come back to them at a future date and work on them after the particulars of the system have left the forefront of you mind. With that in mind here is how we approach the Anchor Buoy relationship graph setup.
Anchor Buoy is another of those concepts that like Data Separation require a little bit of additional setup in the beginning, but pays off big when you start using it in conjunction with context independent scripting and our layout design style. The basic idea is to create your Table Occurrences in several tree structures, with the root of the tree being the context that you are actually working in. Here is an example of a relatively simple database relationship structure to help get the concept across. I’ll break down the individual components and why they are setup the way they are after the image.
First off, there are the root tables. In this graph they would be INV__INVOICES and CUS__CUSTOMERS. These table occurrences form the root of their respective contexts and give a clear starting point to the relationships that follow. Let’s take a look at the Invoices tree to delve into how we setup these relationships and why we structure our data around them.
Any time anything happens to an invoice and any information needs to be pulled onto an invoice, the place we start is the INV__INVOICES table. As you can see, all of the basic information we would need for this invoice is available through some relatively simple relationships. If I need to get to the customers billing or shipping address, I can go directly through the customer table to the associated address. This setup allows me to easily and clearly identify the relationships that my data relies upon. For basic information, there is nothing more complicated than that. I would recommend labeling any table occurrences that are based on anything but the basic ID relationship. For example, when I am going to the customer’s billing and shipping addresses I have two separate occurrences of the address table using the same basic naming convention with the only difference being that I append the #shipping or #billing label to the end of the name. And just as a note, because this was the first mistake I made when trying to use Anchor Buoy for the first time, never link a layout to anything but one of the root tables. Using one of the buoy tables that is further down stream than the root can create all types of context issues when scripting and setting up calculations. I can’t stress how many headaches you can avoid by having only one context to that you work in!
Now, calculations. Let’s say I wanted to store the order total on the order record itself, and I wanted to pull the total directly from the order lines associated with the order. Using the base table system, the context I would start in is ORD__ORDERS. From there, I would pull the sum of the order lines from the ord_ORDER_LINES table occurrence. This one calculation will now be the only place where the order gets it’s total price from. So, when I want to display the order total on the invoice itself I would just grab that calculated total from the inv_ORDERS occurrence. Basically the goal is to always set your data structure up so that your base tables do all the work of gathering information and creating contexts that will allow you to easily traverse your data when you are scripting and designing your layouts.
The end goal of using Anchor Buoy and Data Separation is to lay the ground work for a development environment that is simple to understand, powerful to work within and flexible enough to handle most any scenario that a customer can come up with. Once you have this base in place, using our scripting methods and layout design has the potential to greatly reduce the complexity of development. The next post will focus mainly on setting up the basic operating layouts we use and how we script around them to provide fully encapsulated and single point functionality.
Script Triggers: Monitoring and Restoring Tabs
FileMaker 10’s new Script Triggers feature just keeps delivering. You might, at first, think triggers are limited to layouts and fields, but it turns out your triggers can fire with all kinds of objects. In this article we’ll show you how to run scripts when users switch tabs on your tab controls. In the end, we’ll also revisit a common FileMaker problem: tabs switch when you switch layouts. We’ll show you how to solve this problem quickly and easily using script triggers.
Triggers with Tabs
It is unfortunately not entirely obvious, but Script Triggers work with tab controls. Specifically:
The
OnObjectModifytrigger fires whenever the user switches to a different tab. This is probably the most useful trigger for tab controls.The
OnObjectEntertrigger fires when the tab control gets keyboard focus. This happens when it is in the tab order and you tab to it (so a tab gets the thick black border). You can see a tab control with keyboard focus here:

The
OnObjectExittrigger fires when the tab control loses focus. In other words, when you tab away from it.The
OnObjectKeystroketrigger fires when the tab control has focus and you press any key on the keyboard.The
OnObjectSavetrigger never fires for a tab control.
Watching the Tab Change
Once you know all that, keeping tabs on your tabs (sorry) is easy. For example, suppose you want to show a special message under some circumstances when someone switches to a particular tab. Setting this up couldn’t be easier:
- Write a script that does what you want.
For example, it might show a dialog box, calculate a total, set a global, or clear a selection. - In Layout mode, select your tab control, then choose Format -> Set Script Triggers…
The Set Script Triggers dialog box appears. - Turn on the
OnObjectModifycheckbox.
You’ve just told FileMaker you want to run a script, so it asks you which script to run. - Select the script you created in step 1.
When you’re done here, click OK, then switch to Browse mode. You’re ready to test.
As this video attests, your script now runs as soon as the user switches to any tab:
Which Tab
If you watched the video closely, you may have noticed that the scripted dialog box showed which tab was selected. With only one trigger script, how do you manage this? You just have to ask.
FileMaker’s esoteric GetLayoutObjectAttribute function can tell you all kinds of information about objects on your layout. Of particular interest, it can tell you if a tab panel is front most. To use it, though, you first need to give your tabs object names. We’ve showed you how to do this before but here’s a quick refresher. If you’re already an object names expert, you can skip ahead.
- In Layout mode, click on your tab control to select it.
When you click, the first tab gets a thick black border. This tells you that specific tab panel is selected. (You can have an entire tab control selected, without selecting any of its individual panels. You’ll see this in a moment.) - Choose View -> Object Info to show the Object Info palette.
This is where you go to set object names (among other things). Since its a palette, you can simply leave it open while you work through all your tabs. - In the Object Name box in the Object Info palette, type a unique and identifying name for your tab.
You might call it “tab1″ or “customer tab” or whatever you feel is appropriate. - Click the second tab in your tab control.
The second tab comes to the front but it is not selected. Notice it doesn’t have a thick border. - Click once again on the second tab.
This time it gets its thick border. This is important. You can only name a tab panel once you have it properly selected. - Give this tab a unique name, then repeat these steps to name every tab in your tab control.
If you want to find out if a particular tab panel is in the front, it must have a name, so you’re best of naming them all.
Once you’ve given every tab panel a name, you’re ready to start asking FileMaker who’s in front. This part is easy. Here’s the long-but-simple formula to see if a tab is in front:
GetLayoutObjectAttribute ( "myTab", "isFrontTabPanel" )
Notice that this formula only looks at one particular tab panel (in this case it is looking at the panel called myTab so be sure to put one of your tab panel object names there instead). It will return a True result if the tab panel is in front, and a False result otherwise. To determine which of all the tabs is in front, you can check them one by one:
Case(
GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ); "First tab is in front";
GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ); "Second tab is in front";
GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ); "Third tab is in front"
)
Or, in a script:
If [ GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ) ]
# do stuff for the first tab
Else If [ GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ) ]
# do stuff for the second tab
Else If [ GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ) ]
# do stuff for the third tab
End If
Restoring Tab State
Now that you know how to watch for tab changes, and figure out which tab is in front, you can take it one step further, and solve an age-old FileMaker problem in the process. Last year, we wrote up a laborious technique to remember which tab is in front before you leave a layout, then bring it back to the front when you come back. This way, if your scripts have to quickly zip to another layout to get some work done, your users don’t get distracted by tab controls that keep switching back to the first tab.
That technique worked, but it was tedious. You had to write two long and complicated scripts. Then you had to call one every time you leave the layout, and the other every time you come back. What a nuisance.
Using Script Triggers, you can save all the hassle. Now two very simple scripts can get the job done, and they can do it automatically every time you return to the layout.
Note: In fact, this new, simpler version is even better than the old way. The tab will restore itself even if you manually leave the layout and come back later, making things a touch more stable for your users.
First, you need a simple script to remember the front most tab:
Set Variable [ $$FRONT_TAB;
Case(
GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ); "First tab is in front";
GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ); "Second tab is in front";
GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ); "Third tab is in front"
)
]
That’s it (and its really a one line script, although we put it on a few lines here so it would be easier to read. Just set a global variable to the name of the font most tab.
Note: If you have multiple tab controls to keep track of, make sure you use a unique variable name (or repetition) for each one. Otherwise, changes to one set of tabs will impact the others.
Now attach an OnObjectModify trigger to your tab control and set it to run the script. With these two steps complete, a new global variable will always remember which tab you last visited.
Next, you need to make FileMaker restore the front most tab whenever you come to this layout. This part is equally easy. Start with a simple script:
If [ Not IsEmpty($$FRONT_TAB) ]
Go to Object [ $$FRONT_TAB ]
End If
This script first checks to see if the $$FRONT_TAB variable has a value. If it does, it uses the Go to Object step to bring that tab to the front.
Finally, tell FileMaker to run this script whenever the layout loads. You do this with (shocker) a script trigger. Choose Layout -> Layout Setup, then switch to the Script Triggers tab. Turn on the OnLayoutLoad trigger and point it to your script.
Here’s a video showing the tab behavior with and without the triggers:
In the first version (before the fade-to-black) FileMaker switches back to the firs tab every time you leave the layout and come back. In the second, it seamlessly keeps things in order. This magic works whether your user leaves the layout manually, or you do it with script. Easy as pie.
Make the Status Toolbar Work for You
FileMaker 10’s most visible new feature is the completely redesigned Status toolbar (formerly called the Status area). Perhaps because of its prominent position, or because it is such a striking departure from a 20-year FileMaker mainstay, this change has been met with its fair share of controversy. In this article we’ll show you why you don’t need to worry, and how you can make the new Status toolbar work for you.
In FileMaker 10, the standard Status toolbar looks something like this:

If you leave the Status toolbar open, your user will see prominent New Record and Delete Record buttons (among others). At first this might seem nuts. After all, many of you have special buttons on your layouts specifically for record creation and deletion, and you certainly don’t want people willy-nilly switching layouts to the wrong view, confusing themselves in the process. But it turns out you have more control over these buttons than most people realize. You cannot add your own buttons or custom icons, but you can:
- Disable buttons you don’t want your users to click
- Reconnect most buttons to scripts of your own
- Rename buttons to better reflect the terminology in your database
Note: If you have the equivalent menu commands disabled in your database, then the buttons are already disabled too. A database with locked-down user interface in 9 is just as locked down in 10.
Disabling Buttons
There are three ways to disable buttons in the Status toolbar (not all apply to all buttons). You can set up custom record privileges to control who can create and delete records. You can restrict access to menu commands using a privilege set; and finally, you can use custom menus to remove troublesome menu commands. Which you use is a matter of your security and user interface needs.
Custom Record Privileges
Using custom record privileges you can remove the ability for a user to create or delete records for any particular table. When you do, the associated status toolbar button will disable as appropriate. This even works for so called “record level access” privileges. For instance, you can remove the ability to delete a record only once its Status field has been set to “shipped.” When you do, the Delete Record button will disable when you view shipped records.
Setting this up is easy:
In your database, choose File -> Manage -> Accounts and Privileges.
The Accounts & Privileges dialog box appears.Open one of your existing privilege sets, or create a new privilege set.
You’ll probably need to switch to the Privilege Sets tab. If you’re doing this for the first time, it is probably easiest if you duplicate the [Data Entry Only] privilege set so you start off with some reasonable privileges.From the Records pop-up menu, make a reasonable choice.
For example, if you want to remove the ability to delete records of any kind, choose “Create and edit in all tables.” For the ultimate in control, choose “Custom privileges.” This window shows a privilege set configured so users can create records in any table, but can only delete Vendor records:

Once you assign an account to this privilege set, when that user logs in, she’ll see the Delete Record button disabled when she looks at Customer records:
Restricted Menu Access
The record privileges don’t effect the other toolbar buttons (since they have nothing to do with creating or deleting records). Also, for databases where security isn’t terribly important, and preventing casual or accidental unwanted actions is all you need, restricting record privileges can be heavy handed and hard to script around.
For cases like this, the easiest solution is to restrict menu access. If you revisit the Privilege Sets tab of the Manage -> Account & Privileges dialog box, you’ll discover that you can make gross restrictions to the menu commands your users get:

If you switch to Editing Only or Minimal, FileMaker takes away all the powerful commands (like Import and Export, New Record, Delete Record, Find, and so forth). All the associated Status toolbar buttons will disable as well.
Custom Menus
For the utmost in control, you can turn to Custom Menus. This power feature is only available in FileMaker Pro Advanced, and gives you almost complete control of the menus, sub-menus, and commands your users see when they use your database. You’ll see some step-by-step instructions for using custom menus at the end of this article. For now, it will suffice to say that if you remove a menu command from a menu set, then when that menu set is active, the associated button in the Status toolbar will be disabled. In this way you can selectively disable any button you choose.
Renaming and Redefining Buttons
Disabling buttons is all well and good, if you’re a fan of taunting your users with permanently-out-of-reach temptation. But why not take it a step further. Embrace those buttons and make them do your dirty work. Taking control of the toolbar buttons requires use of custom menus (and, by extension, FileMaker Pro Advanced).
Imagine you have a database of customers and vendors. Your business rules require that you carefully control the process of creating and deleting records. For instance, you may need to set up web site access for any new customers, which requires running your fancy SQL scripts. Here’s how to express your authority and keep the Status toolbar buttons:
- From the File Menu, choose Manage -> Custom Menus.
The (quite complex) Manage Custom Menus dialog box appears. This is grand central station for every menu command FileMaker can muster.
Note: In this example, you’ll use the “Custom Menu Set 1″ menu set FileMaker creates for you. Adjust the steps as necessary if you have your own custom menu sets already.
- In the Custom Menus tab, select the Records Copy menu.
FileMaker ships with a customizable copy of all the standard menus to make it easy to squeeze small changes into otherwise-normal menus. This is the copy of the usual Records menu, where the New Record and Delete Record commands live. - With the menu selected, click Edit.
The Edit Custom Menu dialog box appears. On the left side, you see all the menu items in this menu. - Select the New Record menu item.
When you select a menu item, the right side of the dialog box fills in with options for the item. There’s lots of power here, so feel free to explore. You can see the options here:

- Look next to “Command” and make sure it says “New Record.”
This is the key to this entire technique. This menu item is associated with the New Record command, which is a core command in FileMaker. When you adjust the behavior of the menu item associated with the New Record command, you also modify the behavior of the New Record button. - Turn on the Action checkbox and select the script you use to create new records.
When you add an action to the menu item, you get to pick either a single step or a script. In most cases you’re best off using a script (even if it is a one-liner) because it makes it easy to change later, even if several different menu sets include items that do the same thing. - If you want, turn on the Title checkbox, click its associated Specify button, and enter a calculation to determine the menu title.
For instance, you might decide you want your menu called “New Customer,” “Create Record,” orPi * Random. Ok, probably not the last one, but the point is, you can use all the power of calculations to generate a dynamic and interesting title for your menu. Anything you do here will also influence the label under the New Record button in the Status toolbar. - Select the Delete Record menu item and configure as you wish.
Just make sure you keep Command set to “Delete Record…” so FileMaker knows you’re adjusting behavior for the delete action. - Click OK to close the Edit Custom Menu dialog box.
You’re now back in the Manage Custom Menus dialog box. - From the “Default menu set for this file” pop-up menu, choose “Custom Menu Set 1.”
When you make this change, you’re telling FileMaker you want the customized menu set to be used automatically for this database. You can also configure custom menu sets on a per-layout basis (See the Layouts -> Layout Setup dialog box in Layout Mode) or switch menu sets via scripts (using theInstall Menu Setscript step). - Click OK once more to close this dialog box.
Now you’re ready to test your changes. If all went well, the New Record and Delete Record buttons in the Status toolbar now bend to your will.
Dealing With the View As Buttons
The steps above show you how to attach your own actions to the New Record and Delete Record toolbar buttons. But at the outset, we also mentioned the potential confusion your users might get by accidentally clicking the View As toolbar buttons. Once again, you have two options here.
To disable any of these buttons you can disable a particular view on a per-layout basis. For instance, your Customer List layout only makes sense in List view, so turn off Form and Table views. This is super easy. In Layout mode, choose Layouts -> Layout Setup, switch to the Views tab, and uncheck the views you don’t want your users to use. When you do, the associated buttons in the Status toolbar will be disabled.
Note: You might take this opportunity to disable Table view in many of your layouts, since it has some potentially unwanted power. We discuss this in more detail here.
To get these buttons to run your own script, just override the View as Form, View as List, and View as Table commands using custom menus. You’ll find them in the View Copy menu if you use the built in custom menu set.
To Infinity and Beyond
Combining the various custom menu techniques, plus some clever naming conventions and scripts, you can get the Status toolbar really working for you. In this video demo, you can see a simple database that customizes the behavior of several toolbar buttons so this standard FileMaker user interface integrates seamlessly with your carefully controlled database.
Note: You can download the database in this video right here: My Database.fp7
In this example (which is anything but fully baked) we use the Get(LayoutName) function and some custom scripting to get the “View as Form” and “View as List” buttons to switch to appropriate layouts. We’ve also added a custom script to the New Record and Delete Record buttons, and renamed them so it is more obvious what they will do.
This kind of integration has several powerful advantages:
FileMaker takes care of a lot of nice user interface work that we would otherwise have to create (and duplicate on every layout) ourselves. That means less time fiddling and more time making databases meet the needs of our customers.
This database has more powerful interface elements than it would if we had to handle the UI ourselves. For instance, our end users can show and hide the toolbar at will, and customize it to their needs.
If we build multiple databases for the same customer, they all work the same way. If a user customizes the toolbar in one database, his changes will apply in all of them. He only has to learn one set of interactions. This means we get more consistency with less work.
A lot of people have expressed frustration about the new Status area, complaining that FileMaker has taken away control they need. I hope this article makes it clear that we have more control than ever before.
Opinionated Note: A lot of the frustration about the Status toolbar seems to stem from the fact that it is now more obvious that you can, for example, delete a record. These commands used to be squirreled away in menus, and now they’re front-and-center. But of course a less visible menu command is just as dangerous in the wrong hands. So the new toolbar, perhaps, has simply made it more obvious to developers that they need to be careful.
The reaction to the new prominence of these commands illustrates another interesting reality. Menus have become no-man’s land. More and more in modern, popular applications, the commands you need are readily available in an explorable, friendly busy-box of interface goodness. People expect to see what they can do. I think this phenomenon really underscores the wisdom in the new Status toolbar. To keep current, FileMaker has to get a more modern user interface. It did, and suddenly people notice what FileMaker can do. That is, in my opinion, A Good Thing™. Editorializing over.
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.





