Accordion navigation is a common design pattern in both web and desktop applications. A quick look at admin templates shows the predominance of this method of navigation.
A search for admin templates shows how common vertical, accordion navigation is in data driven web design.
This design pattern has been a bit tricky in FileMaker Pro. Portals have been successfully used in the past, as I’ve described in this thread. One of the issues with using a portal for accordion navigation is that a relationship must be created between the navigation table and every table occurrence where you want the accordion navigation to appear.
Another method is now available, thanks to the new Card window in FileMaker 16. With Card windows no relationships are required, which greatly simplifies the relationship graph. In this document I’ll walk through one method for creating vertical, accordion navigation. I’ll use the Inventory starter solution that comes with FileMaker Pro 16. The end result will have three stages:
- Level 1 Displayed
- Level 2 Displayed
Those states look like this:
From left to right, the three stages of accordion menus in FileMaker Pro using a Card window: Hidden, Level 1 Displayed, Level 2 Displayed
Step 1: Define Navigation List
The first thing we need to do is determine what will be in our navigation. This can be done inside FileMaker Pro, but I prefer to use a text editor for simplicity. That way, I can create and manipulate the list before I’m ready to create data records. It’s ok if we don’t think of everything at the beginning. And, in fact, I’ve purposely left one out. As we’ll see later, adding additional items to the list is fairly simple. Here’s the first run at a list:
That’s the level one list. Each of those will have a sub-menu, which I’ll call Level 2. So the expanded list looks like this:
Show All Companies
Show All Customers
Show All Vendors
Show All Items
Show All POs
Show Pending POs
Show Closed POs
Show All Receipts
Show PO Receipts
Show Return Receipts
Show Transfer Receipts
Show All Put-away
Show Pending Put-away
Show In Progress Put-away
Find Sales Order
New Sales Order
Show All Sales Orders
Show Pending Sales Orders
Show Closed Sales Orders
Show All Picks
Show Pending Picks
Show In Progress Picks
Show Completed Picks
Show All Shipping
Show Pending Shipping
Show In Progress Shipping
Show Closed Shipping
Unit of Measure
Unit of Measure Conversion
Step 2: Select the File
Now that we have out list we can go into FileMaker Pro and start to build the navigation. To download the Inventory starter solution from FileMaker Pro, go to the application’s horizontal menu, File/Get Started…
Accessing the starter solutions from FileMaker Pro 16.
Once inside the Get Started window, scroll down to the Inventory starter solution and click the “Create from This Starter Solution” template.
Step 3: Menu table and fields
Card windows enable developers to display data from a different context without leaving the original context. In other words, we are able to see data in a different table. So the first thing we need to do is create that table. Open Manage Database (File/Manage/Database…), click the Tables tab and add a new table. I’ve named the table “Menu”. Double click the newly created table to navigate to the Fields tab for Menu. We’ll need four fields:
- labelName - Text
- level - Number
- sortOrder - Number
- sortOrderList - Summary = List of sortOrder
Step 4: Layouts
When we created the new table, a new layout should have automatically been created. Go to the Manage Layouts window (File/Manage/Layouts…). If “Menu” is not at the bottom of the list, then go to the bottom of the Manage Layouts window and click “New”.
I use two layouts for this technique. One is a user interface layout - in other words, the navigation menu itself - and the other is a set up layout. So let’s change the name of the first Menu layout from “Menu” to “Menu User Interface”. Duplicate that layout and change the name to “Menu Setup”. Unmark both of them so that they do no appear in the Layout drop down list.
Two new Menu layouts in the Manage Layouts window. Note that both are unchecked so as to not appear in the Layout drop down.
Step 5: Importing the Data
Go to the Menu Setup layout. We’ll need to get the list data into this table (unless you typed the list directly into FileMaker Pro). If you used a text editor you can import that into FileMaker Pro. However, if you used tabs, as I did above, then FileMaker may not place the data in the correct field. There are a number of ways to prevent this and a few more to correct it. Its a bit of a rabbit hole to go down all the possibilities, so I’ll describe one corrective method.
Here is what the Menu Setup layout looks like in Table View after I imported the text file:
The tab in front of the level 2 text string imported into the level field.
The first thing I want to do is set the correct data for the level 1 labels. It will be easy to find. I’ll search for all the records where the level field is empty:
Now, that I have all the level one fields selected, I can easily set the level field of one of the records to 1 and Replace Field Contents (Records/Replace Field Contents…). Make sure that you only have the found set you want to change. There is no undo for Replace Field Contents.
Now I can go into labelName and find all the records where that field is empty:
Again, making sure that you have the correct found count (because Replace Field Contents cannot be undone), set labelName field to be the same as the level field. To do this, go to Replace Field Contents (Records/Replace Field Contents…), select the radio button “Replace with calculated results: Specify…”:
While we’re in this found set, we can also change the level field to 2. Change the level field of one of the records (it doesn’t matter which one, as long as we’re still in the correct found set) and change it to 2. While still in that field, select Replace Field Contents (Records/Replace Field Contents…):
The Menu data should now be correct:
Step 6: Set the sortOrder
Now that the data is in the proper fields, we need to set the sort order. This will determine how the records in the Card table will display on our menu. You could create a script to loop through the list and set the sort order or you can set the field manually. I did the latter. In our example, that means modifying 71 records.
The convention for the sort order is such that level one records are whole numbers, starting at 1 and incrementing by 1, so
and so on.
The child records have their parent number followed by a decimal and then another number, starting at 1 and incrementing by 1. The exception to this is that the last level 2 record in each list ends in .99. This is for a UI (user interface) trick that I’ll explain later. So now we have the data all set:
But what happens if we want to add or change the list? For example, when I created my original list above, I didn’t add Transfers. I’d like to add that to my Inventory navigation and I’d like it to go above Admin. That means that the Transfer records for level 1 and level 2 will have a sort order of 9 and all the Admin records will need to get bumped up to level 10. To do that, I’ll find all the Admin records by searching for 9*. Once I have that found set, I can use Replace Field Contents (Records/Replace Field Contents…) and replace with a calculation.
There are a number of ways to do this. I used the Substitute () function. It doesn’t change the level 1 field, but it gets all the level 2 fields. I can then manually change the level 1 field from 9 to 10.
Once I’ve done that, I can add the Transfer records, setting the level and sortOrder fields manually:
Step 7: Layout Design
Once the data is set, we can turn our attention to the layout design for the accordion navigation. Go to the Menu User Interface layout that we created in Step 4 above. Set this layout to be a list view. We’ll need a header. A footer is optional; I’ve kept the footer.
At the bare minimum, we only need 3 objects, all of them single button button bars.
The first button we need is a way to close the Card window. That will go in the header. For this icon I wanted a hamburger menu (3 stacked, horizontal lines) with an arrow. FileMaker doesn’t offer this in their suite of icons, so I used Icon Manager V16 by inDats. This is a fantastic tool, in my opinion and its my first “go-to” source when looking for icons to supplement FileMaker’s native icon library.
The button to close the window is a simple single step button that closes the current window. If you need additional activities to happen upon closing the navigation window, then you’ll want to run that from a script instead of a single step.
Technically, this first button can be a button object instead of a button bar, but for simplicity’s sake, I made them all the same object type, namely single button button bars.
The next two button bars are also single buttons. They are text only at this point. We’ll add icons further below. But you don’t have to add the icons. If text alone works for your solution, then it simplifies the process. Text for both of the buttons comes from the label name. Double clicking the button bar brings up the button bar set up dialog where you can select the field:
We need two things to differentiate these two button bars:
- Hide criteria
The first, color, adds visual appeal as we open and close the accordion. It will indicate that added options are now available to the user. When you use color to differentiate level 2 from level 1, make sure you know your users. According to the website www.colorblindawareness.org, approximately 1 in 12 men and 1 in 200 women are affected. Check with your users before selecting colors for differentiation.
For the purposes of this demo, the level 1 button is the Default style and the level 2 button is the Body Button Bar.
The next thing we need to do is make sure the correct button is showing. Remember, when we display the Card window for our accordion navigation, we’ll be showing a list view with two buttons in the body. But we only want to see one of those buttons per record. To do this, select the level 1 button bar (the one with the Default style) and in the inspector set this object to hide under this condition:
Menu::level <> 1
For the level 2 button bar (the one with the Body Button Bar style), set the condition to this:
Menu::level <> 2
The last thing to do is to stack the buttons. Stacking objects used to be a pain in FileMaker Pro. But in FMP 16 we now have the Layout Object Window, so making modifications is relatively easy. Here is the layout, with the stacked button bars (level 1 button bar is underneath level 2 and not visible):
Step 8: Displaying the Accordion Navigation
Now we need to display our accordion navigation button on the different layouts. I’ll be using the Products Details layout for this demo. I want the accordion menu on the left hand side, so I need to put a button in the upper left corner. There is already a button there (< Inventory List), so I’ll delete that object and change to a new, single button button bar. Again, I wanted a hamburger icon with an arrow, so I’m using an icon from the InDats Icon Library:
And here is the script for the new button:
New Window [ Style: Card ; Name: “Menu” ; Using layout: “Menu User Interface” (Menu) ; Height: 725 ; Width: 250 ; Top: 0 ; Left: 0]
Enter Find Mode [ Pause Off ]
Set Field [ Menu: :level ; 1 ]
Perform Find [ ]
Sort Records [ Restore ; With dialog: Off ]
Exit Script [ Text Result: ]
This script opens the Accordion Navigation menu in a closed state. That is, it only shows level 1 records.
Here’s the New Window Dialog window:
Positioning the window at 0, 0 puts the new window in the upper left corner. You may need to play around with the Height and Width of the card window to get the right size.
The Sort Records at the end of the script sorts by the field Menu::sortOrder which we set when initializing the data in the Menu table. Once the Accordion Menu is open, the hamburger icon at the top simply closes the current window, as previously mentioned. That creates the toggle effect of the hamburger menu opening and closing the accordion.
Step 9: Toggle Level 2
Now that the main menu is visible, we want to select one of the options in order to expand the menu. A script performs the toggle:
Set Variable [ $sortOrderBase; Value:Menu::sortOrder ]
#only expand for first level
If [ Menu::level <> 1 ]
Exit Script [ ]
#menu is either closed, opened with the current selection, or open with a different selection
If [ PatternCount ( Menu::sortOrderList ; "." ) = 0 ]
#menu is collapsed; open user selected sub menu
Perform Script [ “expand menu”; Parameter: $sortOrderBase ]
Else If [ PatternCount ( Menu::sortOrderList ; $sortOrderBase & "." ) > 1 ]
#this menu item is already expanded; toggle it to close
Perform Script [ “vertical menu” ]
Perform Script [ "vertical menu" ]
Perform Script [ “expand menu”; Parameter: $sortOrderBase ] End If
Exit Script [ ]
There are only three possibilities for the menu:
- It is closed and therefore needs to be opened.
- It is opened and therefore needs to be closed.
- It is opened but on a different selection. Therefore, close that selection first before opening the new one.
To expand the level 2 menu, we call the “expand menu” subscript:
Set Variable [ $sortOrderBase ; Value : Get ( ScriptParameter ) ]
Enter Find Mode [ Pause: Off ]
Set Field [ Menu::sortOrder ; $sortOrderBase & “*” ]
Extend Found Set 
Sort Records [ Restore ; With dialog Off ]
Exit Script [ Text Results: ]
Again, the Sort Records step sorts on the field Menu::sortOrder.
Once the level 2 options are available, users would be able to click those buttons to perform the desired event. (In this demo, I simply have the script open a custom dialog).
That’s the basics of the Accordion Navigation Menu. However, we can do a couple more things to increase its visual appeal.
Step 10: Give It Depth
As it is, the navigation menu is flat. Adding depth to the level 2 menu provides the user with a visual cue that she is within a section.
To add depth, we’ll return to the Menu User Interface layout and add two more objects. The objects are both shape objects, in the form of a rectangle. The two objects are identical in height and width. They differ slightly in color. In fact, they are both gradients. The only difference is that direction of the gradient.
The lines I’m using are 6 pts. tall. You may want to play with the height to see how the gradients appear on your screens.
I’ll place the gradient rectangles at the top and bottom of the Body part. However, I don’t want them to show for all records. They should never appear on a level 1 menu record. For level 2, they should only appear before the first and after the last record. Before the first is easy since we know the first level 2 record has a sort value of n.1 (1.1, 2.1, 3.1, etc.). However, the quantity of level 2 sub menus varies. For example, Company has 8 sub menu records (i.e. level 2 records) whereas Item only has 5. So how do we find the last sub menu record when there is variation?
You may recall in our numbering system we ended each group with n.99 (1.99, 2.99, 3.99, etc.). We’ll never have 99 sub menus (at least, we SHOULD never have 99 sub menus!). And it will also sort to the bottom of the sub menu list. Using that static number for the last record in each set allows us to know where the bottom is. Now that we know the top and bottom we can hide the gradients accordingly.
The top gradient is hidden when:
PatternCount ( Menu::sortOrder ; ".1" ) = 0
And the bottom gradient is hidden when:
PatternCount ( Menu::sortOrder ; ".99" ) = 0
Two gradient rectangle objects, one at the top of the Body part and the other at the bottom. Extended beyond the Body part to help demonstration their location.
Now, with the gradients, in place, the Accordion Navigation Menu has a bit of depth when level 2 is visible. Take a look at these side-by-side comparisons, one with depth and the other flat:
Step 11: Adding Icons
Lastly, we can spice up the menu by making it a bit more visually appealing. To do that, we’ll add icons. Icons present a bit of a problem, however. Unlike the button label, which can vary based on a calculation, the button icon is static for a particular button. There is no way to say:
If [ Menu::labelName = “Company” ]
Else If [ Menu::labelName = “Item” ]
In order to show the icons, we’ll need to change our two button bars from single button button bars to multiple button button bars. If we go back over to the Menu Set layout, we can perform a search for level 1 records and we’ll see that there are 10 records. Level 2 records has 68 records in that found set. However, that doesn’t mean that we need 68 buttons in the level 2 button bar because many of the level 2 records will have the same icon. For example, there are 9 level 2 records with “Find” in the labelName (Find Company, Find Item, Find Pick, etc.). These will all have the same icon. Likewise for “New”, “Last”, and “Show”. What we end up with is a button bar with 11 different icons for level 2 (Last, Find, New, Show, Dashboard, Settings, Warehouses, Locations, Integrations, Unit of Measure, and Unit of Measure Conversion).
Adding the additional buttons to the button bar will not expand the width of the button bar. That’s good because we need to to remain the same width as the single button button bar. That makes for a bit of a tight design area, but not awful.
Once we have our buttons we can add the icons. Each button receives its own, unique icon. Then we’ll need to hide the button accordingly. For level 1, it is pretty straight forward. We hide the button when the labelName does not equal a certain label. For example, the Company icon will not show when
Menu::labelName <> “Company”
Level 2 buttons are slightly different since one icon will be used for several records. The hide calculation for level 2 is
PatternCount ( Menu::labelName ; "Last" ) = 0
In other words, when “Last” IS in the labelName field, then show the icon. And remember, the actual button label is a calculation based on the labelName field, so the text is dynamic.
Here’s what the new button bars look like in Layout Mode:
Notice that the level 2 icons are not showing. In order to create a visual of a tree structure, I set the level 2 buttons with a higher padding than the level 1.
And that’s one way to create an Accordion Navigation Menu with icons:
The demo file is available at FileMaker Inventory Resources.