Wouldn't it be nice to have a button bar that you could place on every layout that handles basic FileMaker navigation and would automatically update itself when you make changes like rearranging, renaming, or adding layouts.
The appeal of this functionality is that it can be applied to most any FileMaker solution. I’ve seen other approaches over time, although not all have met all requirements that I would want of such a tool. These requirements include:
- Works in Browse and Find mode
- Uses Themes and Styles
- Allows manually navigating to layouts
- Works in List View
- Works in Pro (both local and hosted), Go, and WebDirect
- Works with multiple windows
- Works natively (no plugins required)
- Does not require additional schema
- Handles a reasonable number of layouts
- Minimal scripts required
- Does not require custom functions, which is better for portability
- Retains the last visited sub-section, allowing for navigation of multiple tiers
This has been something that has been in the back of my mind for a long time. An earlier version I created used a web viewer to display navigation but only supported two tiers. That solution had its drawbacks, notably a "clicking" sound on Windows that happens when a web viewer is loading. That original version was done some 10-plus years ago and was due for an update using modern techniques.
The newest iteration supports three tiers of navigation and uses only native FileMaker objects. You can also utilize Themes and Styles with current versions of FileMaker, allowing you to easily change the look and feel of your standardized navigation in all layouts that use the same theme. All layouts that use a common Theme will reflect updates across the entire file when you update the Theme.
Three Tiers Deep
This solution has three button bars, first introduced in FileMaker 14, that are stacked on top of one another. Your first tier is the top bar. Therefore, the minimum version of FileMaker for this technique is at least 14. Clicking on one of the top tier buttons takes you to the second tier and so on. If you think of the layout names as data, where we define a delimiter to separate the layouts, we can structure a naming convention that works with the navigation framework to build out the navigation scheme. Consider the following:
This is a straightforward list of values, which is easy to understand. If we consider each individual value as having a list of its own, this could be considered a multi-dimensional array. For example, “Company__Contacts__Info” is a list with three values delimited with an underscore.
In the above list, we have "Home", "Company" and "Prefs" on the first tier, and the second tier would be dynamic, based on the first tier we have selected. Company on the first tier has “Main,” “Details,” and Contacts” that appear on the second tier. Similarly, selecting “Contacts” on the second tier will show “Info” “One” and “Two” on the third tier. If there are no values to display on the second or third tier, that button bar is hidden.
That also means it is easy to change your navigation by simply rearranging the order of layouts. The next time you run the “Load Nav” script, or just close and open the file again, your FileMaker navigation will update through your entire solution.
Building the List
Since we can get all the layout names with a Design function, it is possible to parse through those values to build a series of global variables that will display those values on a button bar. Once we determine which first-tier section we are on – based on the current layout name – we can evaluate which second and third tiers need to display.
You may optionally set your own list of layout names to use, instead of using the design function. That gives you more control over naming layouts you do not want to appear, or layouts that may physically be out of order. If you want to keep it dynamic, there is a developer definable prefix to use that will omit layouts you do not want included. If you override with a static list, you can simply include only those layouts you wish to appear.
This solution supports up to three tiers, with each tier being able to support up to ten values. That means 10 x 10 x 10 for a total of 1,000 layouts that can be maintained automatically. That should suffice for most of the solutions that I work on.
Order is important
Since we parse through the layouts to build the navigation interface, those layouts need to be in the order you want them to appear. This makes it trivial to update your user interface. Did you want "Prefs" to appear before "Company"? Then simply re-order your layouts and open the file again. Your UI will update to reflect the change.
To populate all the needed variables, we need to run a script once when the file opens. In this version, all the buttons in the button bar get routed through a centralized “Nav” script, where exceptions can be handled. Alternatively, that script can simply use "Go to layout" by name.
We also handle support for multiple windows in the “Nav” script if the user holds down a modifier key. The command key on OS X, the “ctrl” key on Windows, or the shift key will open a new window before navigating to the desired layout.
Dynamically named variables
The solution makes heavy use of dynamically named variables, so it may limit the characters used in layout names because they are used to name variables. If your layout names follow the naming convention explained above, it all just works. Global variables are all “namespaced” with a "NAV" prefix to avoid collisions with other variables you may set in your solution.
FileMaker supports Unicode pretty much everywhere, so you can include emojis in layout names. They will display as icons in the navigation bars. Note: this also means you can have emojis in variable names.
Under the Hood
Button bars make it possible to use calculations to specify the active button segment. The calculations that determine which segment should be active for each of the three tiers are dependent on each other. For example, to know what the active segment should be for the second tier, we need to have already calculated the active segment for the first tier.
So that we can more easily control which active segment is calculated first, the three active segments are determined using a single calculation, which has been placed in the top-most button bar. Layout objects are rendered left-to-right, top-to-bottom, so once the first-tier button bar evaluates its active segment calculation, the next two button bars will be ready to go.
Second and third tiers with a null value are assigned a default value to display, like "Main." Buttons that are not used are hidden so that they cannot be clicked. The remaining space is filled in with invisible buttons that have no action assigned to them and act as filler, so the buttons stay at even width.
If there are layouts you do not want automatically included in your navigation, you can exclude them by naming the layout beginning with "//". The notations used for the delimiter and exclude flag are configurable in the script that loads the navigation variables. If you want to use a different convention, you can change it to whatever you want, but the default is double underscore for tier delimiters and double slash to exclude the layout.
This screenshot shows what the navigation scheme looks like. You can also see this in my accompanying demo file, which includes some sample layouts. The different tiers have been styled differently to set them apart.
The next screenshot shows how navigation appears when viewing the "Company__Contacts__Info" layout.
Because button bars are easy to manage, you can modify their placement and appearance easily. Would you rather display the third tier at the bottom of the layout? Just place the third button bar at the bottom of the layout. Layout size is wider than the sample file? Just resize the button bars to the desired width, setting the anchor points as needed.
Save Your Place
In each section, we can retain the last visited sub-section when navigating multiple tiers by setting the variables used to link to different layouts when navigating through the lower tiers. You would not want to keep having to navigate through 2nd and 3rd level tiers every time you go to “Company” for example. If you are drilled down, need to go to “Prefs” and go back to “Company,” you will arrive at the 2nd or 3rd tier you last visited.
As we use global variables unapologetically, each window gets its own set of global variables to reference. These are set in the scripts and buttons, so there is nothing for you to update; it is all done for you.
Is this a little heavy-handed, brute force setting so many variables? YES! But the work is done all up front and only once, so you can benefit from it in lots of places.
Dynamic FileMaker Navigation Bar Instructions
To use this in your own solution, follow these steps:
- Import the Theme, or create styles for the parts. This can be done later if you already have a Theme in use.
- Copy the "Load Nav" and “Nav ( layout )” scripts, paste it in your solution, and configure “Load Nav” to run when the file opens.
- Copy the navigation buttons bars and paste them into your layouts.
- Configure a script trigger to run when opening a new window (File->File Options…->Script triggers: OnWindowOpen) to include the “Load Nav” script. If you do this, you can disable the script steps to run this script when checking for a modifier key in the “Nav ( layout )” script.
I will often use this technique on files that I have developed where I do not have time budgeted for layout navigation. With this solution, I have nice looking navigation available that can be implemented in a short amount of time.
Try it yourself. Download the sample file.
If you have any questions about building your own dynamic FileMaker navigation functionality, please don’t hesitate to ask a question below or contact my team and me directly.