Making Multi-Window Navigation History in FileMaker Pro
Making your FileMaker Pro solution easy to navigate is key to providing a great user experience in your solution. WoodgeNav is a free FileMaker navigation solution that builds on existing examples to improve the functionality.
Anybody who has used a web browser knows what the back and forward buttons do. It’s expected that you can navigate to a new page, the go back to a list and look for another item. This behaviour has become so ingrained that if software doesn’t do this it can just feel broken. If we build a website or web-app we get this behaviour for free. In FileMaker Pro this requires a little bit more work.
A quick Google will reveal many existing solutions to this problem:
Paul Jansen, APJ Ltd
https://www.filemakermagazine.com/videos/adding-back-buttons
ISO FileMaker Magazine
https://www.youtube.com/watch?v=HMVDqHWvklY
Accelerate Computer Training
These are all good solutions, but none of them quite gave me the behaviour I was looking for. The key points for me were:
Backward/forwards navigation function, keep track of where the user has been.
Multi-window support with seperare history per window.
Ability to show not just the layout name, but record specific information for previous pages if required.
Neat, compact appearance that behaves the way a user expects it to behave without a steep learning curve.
Not too onerous for the developer to keep on-top of.
Getting Started
I used Paul Jansens BrowserNav as a starting point but with a few key developments and improvements. I wanted to be able to have the user CTRL click the back button and be shown a list of the previous layouts they were on. Using a popover and a button bar with calculations.
The Custom Function BrowserNav.History was updated to allow it to be called its a specific number of steps back into the history. It was also updated to return either the Name, Number or Hide status of that history item.
Let ([ ~w = Position ( Substitute ( Filter ( Substitute ( ¶ & $$BrowserNav.Windows & ¶; ¶ & Get ( WindowName ) & ¶; "¶•¶" ); "•¶" ); ¶; "|" ); "•"; 1; 1 ) - 1; ~valueNum = numBack + 1 ]; Case ( type = "Name"; GetPipeValue ( GetValue ( $$BrowserNav.Layout.backward[~w]; ~valueNum ); 3 ); type = "Number"; GetPipeValue ( GetValue ( $$BrowserNav.Layout.backward[~w]; ~valueNum ); 2 ); type = "Hide"; IsEmpty ( GetValue ( $$BrowserNav.Layout.backward[~w]; ~valueNum ) ); "" ) )
Each segment in the button bar will look up that history from the correct global variable for the current window name. If that repetition is empty the button will be hidden. This logic is only evaluated when the pop-over is shown, so it doesn't slow the layout down too much.
When one of the navigation history buttons is clicked we pass the number for the history entry we want. We then lookup the list of window names so we can get the right global variable repetition. From there we can get value number from the global variable and return the layout number. We can then go to that layout by it’s number.
This code could be updated to use a JSON structure rather than pipe spaced values, but unless you use the pipe character ‘|’ in your layout names, it should work fine as is.
It’s also worth noting that if new layout are created, deleted, or reordered in a live system then the LayoutNumber will change. But hopefully you’re not making too many live changes while your users are in the system!
In most web browsers the default behaviour is to just go back one step when you click the back button, but to show a list if you CTRL click it, so lets see how we can do that in FileMaker Pro.
A popover button can be used, with another button bar inside popover. We can add a script trigger to the popover it’s self (not the button) with the event OnObjectEnter fire a script.
Here we can check for any active modifier keys held down (shift, ctrl, alt, windows key etc), if so Exit Script: True and the popover will appear. If false the we can load the last item from the nav list.
As we open and close windows we need to keep our list of window names inline with the repetition number for the global variables we are using to save the history.
With the original version of BrowserNav if you closed say the third window out of four then the references would get mixed up when another window was added.
To get round this I added an OnWindowClose script trigger to manage the global variables. By finding the number Window Name in the list, we can the renumber the reference to any subsequent windows.
Using Let and Evaluate here allows the global variables to be looped over and have their repetition number recalculated. We will need to be careful as the code inside the Evaluate is a literal string, FileMaker warn us about syntax error and won’t be included in any analysis tool like FMPerception.
Evaluate ( "Let ([ $$BrowserNav.Layout.backward[" & $i & "] = $$BrowserNav.Layout.backward[" & $i + 1 & "]; $$BrowserNav.NavBackTip[" & $i & "] = $$BrowserNav.NavBackTip[" & $i + 1 & "]; $$BrowserNav.NavNextTip[" & $i & "] = $$BrowserNav.NavNextTip[" & $i + 1 & "] ]; True )" )
So the final modification is to make it easy to add calculated text to the description of the history item.
By adding an off screen textbox to the layout, it’s possible to call the function BrowserNav.Save This way the layout is only added to this history if the object is added to the layout. We can also include records specific information in the history as well.
We only want to include the most recently seen record for a given layout, so we need to make sure we don’t add to the history as the user might browse next/previous records.
Global Navigation Bar
Also included in the download file an example global navigation. This simple system allows you to specify a set of icons, labels and layout names for a neat system wide navigation bar. You can also hold down CTRL to open the layout in a new window.
The above screenshot shows the config layout where you set up the navigation. When the file opens the nav items are loaded into a set of repeating global meaning the nav bar can be added to any layout. I’ll cover how this works in a follow-up article.
So feel free to download the sample file and use it for anything you want.
If you have any questions, suggestions or want some help implementing into your solution drop me a message.