Whether you're a newbie or a FileMaker Pro guru, you'll undoubtedly have to provide scripted buttons to navigate through the plethora of layouts in your solution. The idea behind this technique is to track all the layouts visited by a user. The implementation is similar to the Back and Forward buttons on a Web browser.
A Web browser lets you go backward and forward through the Web pages you visit. You can move back through the Web pages you've visited and forward through the Web pages you've backed through. Whenever you navigate to a new Web page, the stack of forward Web pages is removed and only repopulates when you navigate backward through your history. To replicate this Web browser functionality in FileMaker Pro, you have to stack your visited layouts into an array each time you visit them using a navigation button. In this example, a global repeating variable acts as the array.
The first script you compose is the open script, which creates the global variables by initializing them. The open script wouldn't be necessary if you didn't want to track the initial layout where a user starts. A good example would be a main menu screen. If you decide to add the starting layout to your history, run the following script upon the opening of the file using File Options:
Go to layout ["Main Menu"]
Set Variable [$$pointer; Value: 1]
Set Variable [$$stack[$$pointer]; Value: Get(LayoutNumber)]
As you can see, the $$stack variable stores the layout number of the initial layout. In the upcoming scripts, you'll see how the $$pointer variable determines in which repetition of the $$stack array the layout number will be stored.
Each time you navigate to a layout, you'll have to run the following sub-script, called Stack Add:
Set Variable [$$pointer; Value: $$pointer + 1]
Set Variable [$$stack[$$pointer]; Value: Get(LayoutNumber)]
This sub-script adds each newly visited layout to the next repetition in the repeating $$stack variable using the incremented $$pointer. You'll also have to run another sub-script called "Stack Remove" to remove the forward history:
Set Variable [$reset; Value: $$pointer]
Loop
Set Variable [$reset; Value: $reset + 1]
Exit Loop If [IsEmpty($$stack[$reset])]
Set Variable [$$stack[$reset]; Value: ""]
End Loop
Essentially, this sub-script loops through all the repetitions in $$stack after the current $$pointer and sets them to blank, thus erasing the forward history. A good way to understand this script is to slow it down using the Script Debugger so you can step through it line by line. You'll also want to display the Data Viewer so you can see the global variables change.
Here's an example of what one of your navigation scripts may look like:
Perform Script ["Stack Remove"]
Go to Layout ["MyLayout" (MyTable)]
Perform Script ["Stack Add"]
Again, the Back and Forward navigation buttons work much like you'd see in a Web browser. When you click on the Back button, you walk through the layouts stored in the stack. Here's the Back script:
Set Variable [$$pointer; Value: $$pointer - Case($$pointer > 1; 1)]
Go to Layout [$$stack[$$pointer]]
The Case statement in the Set Variable script step decrements the pointer so you're backing through the history of layouts. However, you don't want to decrement the $$pointer variable after you've reached the first repetition of the array. After you've decremented the $$pointer, the Go to Layout script step with the option "Layout Number by Calculation..." visits the correct layout in the stack using the $$pointer variable. If you're unfamiliar with how to reference repeating fields in a calculation, you simply specify the field or variable followed by the repetition number in square brackets. In this technique, another global variable provides the repetition number.
The Forward button script is similar to the Back button script:
Set Variable [$$pointer; Value: $$pointer + Case(not IsEmpty($$stack[$$pointer + 1]); 1)]
Go to Layout [$$stack[$$pointer]]
The big difference is the Set Variable script step increments the $$pointer variable. It also must check if the last layout in the array has been reached using a Case statement so as not to increment the pointer beyond the stored layouts.
Mingchao Yin originally sent me an example file and article demonstrating this technique. I've changed his technique significantly but wanted to give him credit for spawning this tip.