Build a Navigation System Part Two - Taking it Further

By Daniel Wood, 6 June 2011

In part one, we built a basic navigation bar made from repeating fields. In this followup article we take the formatting of the navigation bar further by introducing highlights. We also adjust the construction of the navigation, and introduce a custom menu implementation that can be used in conjunction with, or in place of the navigation bar.

Some changes to the construction

In order to make some of the new features of this upgraded navigation bar easier to manage, we are going to make a few minor tweaks to how the navigation bar is constructed. These changes may slightly affect how the navigation bar looks from earlier versions, but these can easily be overcome with field formatting options.

navigationbartwo 1

On first glance it may look very similar to the navigation bar in part one, but there are a couple of changes that are shown better in layout mode.

navigationbartwo 2

Here, the icon repeating fields have been increased in height so that their bottom border touches the top border of the label repeating fields, creating a single block with no gaps in between the icon & the labels.

Another change less noticeable, is that each icon/label combination has been created as a separate series of objects to the other repetitions, better illustrated in the following picture:

navigationbartwo 3

Recall in part one that we specified the icons and labels as single fields that were set to show all repetitions. There are a few reasons for this change which will become clear later.

One final change is that each repetition combination of icon & label are grouped into a single object.

Highlighting the Selected Screen

The navigation bar in part one gave no visual indication of which screen the user was currently viewing. It would be nice to highlight the screen being viewed so the user is not left guessing where they ended up, it also provides some solid feedback that the users click on the navigation bar was successful.

What we are going to do then is to implement some highlight formatting as shown below:

navigationbartwo 4

In the picture above you can see two things happening:

  • Background filled white
  • Text label changed to black & bold

Both of these formatting changes have been done by using conditional formatting.

The decision to use conditional formatting over calculation fields that make use of text formatting functions is a conscious decision. The downside to the conditional formatting is that if you ever want to change the fill color or label changes, then the change has to be applied to all navigation bars (or a single navigation bar that is then replaced on all layouts). This could become a nuisance but we are going on the assumption that once set it won't change. The fact the entire navigation system is based on globals means changes aren't that difficult to make as it is a case of copy/pasting a new navigation bar on all layouts that use it.

The reason why calculation fields that use text formatting functions were not used for the formatting, is because the goal here is to keep the navigation system entirely global. By having it all global based, there is only the need for a single Navigation table occurrence on the graph, and navigation bars can easily be applied to new layouts without additional setup. Global calculation fields are not suitable in this situation as they do not refresh as desired.

The conditional formatting calculation

NOTE: This section is somewhat irrelevant now after a discovery by Peter Bouma after the article was written. Please see the extra section at the bottom of this article before reading this section as it may save you some time, cheers :-)

In order to highlight any particular screen in the navigation bar, we require a calculation that can be evaluated that is generic, but at the same time evaluated differently for each repetition. How can a specific repetition evaluate differently from another repetition you ask? Well the answer lies in using a FileMaker function that will give a different result depending on which repetition evaluated from, and there are two prime candidates:

  • Get ( ActiveRepetitionNumber )
  • Get ( CalculationRepetitionNumber )

Both of these are concerning repeating fields so have potential. Get ( ActiveRepetitionNumber ) however is of no real use because that only evaluates when the user has placed the mouse cursor inside of a repeating field. Because we have disabled browse mode access into our navigation bar, this function will never evaluate.

The other possibility is Get ( CalculationRepetitionNumber ). This function will return a repetitions number when evaluated from a calculation context of that repetition. There is just one problem here, our navigation bar is composed of non-calculation repeating fields. The solution then is to make it based on calculation repeating fields :)

navigationbartwo 5

In the picture above you can see two new fields added to the Navigation table - Labels Display and Icons Display. Both are global calculation fields set to their equivalent non-calculation field.

'Scuse me Egon, you said using global calc's was bad

Now, we mentioned earlier that we chose not to use global calculations to do the formatting, yet here we are using global calculations, what gives? Well in this situation they are fine because they will be used only for the navigation bar, and not formatting. Global calculation fields will re-evaluate when fields they reference are changed, but they will not change however when non-field references in them change, such as the current layout name.

navigationbartwo 6

Here is the new navigation bar above, based on the global calculation fields. Note the label definition is not visible because the label text is white by default.

Now that the navigation bar is based upon global calculations, the Get ( CalculationRepetitionNumber ) field can be used in the conditional formatting. Here is the conditional formatting calculation we can apply across all repetitions:

Get ( LayoutName ) = Navigation::Layout Names[Get ( CalculationRepetitionNumber ) ]

It is simply comparing the current layout name, to the layout name contained in the Layout Names field repetition that corresponds to the current repetition being evaluated. For example, the 5th repetition in the nav bar will compare the current layout name, to that in the 5th repetition of the Layout Names field. If it is a match, the conditional formatting will evaluate to true.

Changes to make applying conditional formatting easier

Recall earlier the changes made to the navigation bar construction. These were done for various reasons, but one is to make the conditional formatting of the nav bar simpler.

navigationbartwo 7

The grouping of the label and icon repetition means that we can apply a single conditional formatting property across the single object that takes care of both the highlight and the text formatting, no need for a separate condition for the label and the highlight.

navigationbartwo 8

This single conditional formatting condition can be applied across the entire navigation bar in a single hit, because it is generic across all repetitions. The text formatting of bold & text color will have no affect on the icon, and the fill color will be applied to both icon and label which is what we want.

Note that in order for the highlight fill to work correctly, your icons should be transparent png's or gifs.

A custom function for conditional formatting

While not strictly necessary, we have used a custom function in the example file to contain the conditional formatting calculation. This is a nice illustration of how custom functions can actually reference fields - so long as those fields are able to be evaluated from the context of where the custom function is evaluated from.

navigationbartwo 9

navigationbartwo 10

Clickable area in the Navigation Bar

Now that the text label and icon are touching borders, and they are grouped, we can just make the clickable button the grouped object. This removes the need for a separate button overlay which was used in part one. The reason it was used there was because our icon and label were not aligned and the same size as the clickable area. Because of this change, we can remove the button overlays, reducing the complexity of the navigation bar.

navigationbartwo 11

Building Navigation into a Custom Menu

With the navigation system completely global and already built, building it as a custom menu is a piece of cake.

To do this, we use a technique demonstrated in a previous article called Hide Custom Menu Elements Dynamically.

The technique consists of creating menu items in a new menu. The name of each item is set using a calculation to a specific repetition of the labels repeating field. Because this is global based, it should work across all layouts where the menu item is used.

When building a custom menu, there is no ability to soft-code item names making use of the menu items position in the menu. For this reason, each menu item's name is set from an explicit repetition of the Labels field. Because we may not know exactly how many repetitions of the navigation bar a solution may use, we accommodate for this by adding as many menu items as possible. Menu items will not display if their name evaluates to blank. This is the technique outlined in the article above, and for this reason we can be sure that the menu will only display items for just those that are in the navigation bar.

navigationbartwo 12

The picture above illustrates how the custom menu is built, and the fact that unused repetitions contain no name, and so will not be displayed in FileMaker 11 (in FileMaker 10 they display as blank, but have no action).

The menu item name is set via the Labels repetition, and the action attached is a script that is passed a corresponding repetition number.

navigationbartwo 13

We have gone from using a single script step for the navigation, to putting that inside a script. The reason for this is one of future-proofing. If we ever wish to do post-navigation stuff, this lets us add that in later without having to redo the navigation bar or custom menu.

navigationbartwo 14

The above shows the custom menu in action.

If you had a solution with lots of screens, you could choose to do away with the visual navigation bar entirely, and simply use the custom menu aspect for navigation.

Final Thoughts

With a few tweaks and additions, we have made the navigation bar more responsive visually, by having it give feedback on which screen is selected. We also extended it's use by building a custom menu to supplement it. All the while the navigation system has been kept global and generic so that it can easily be applied to layouts with zero modifications required.

Extra: Global Calcs not required via Peter Bouma

As always the readers of these articles come up with some great suggestions and contributions after the article is written and this case, Peter Bouma from Amsterdam, has discovered that in fact the need for global calculations that contain the icons and the labels is not necessary for using the Get ( CalculationRepetitionNumber ) function as I had assumed.

He has found that this function still evaluates correctly even from the context of a layout-based calculation such as the conditional formatting calculation. Even though the original labels and icons repeating fields were not calculations, the function still is able to obtain the relevant repetition via the conditional formatting calculation set on each repetition.

End result is the solution can be made simpler than I originally presented, you can do away with the Icons Display and Labels display calc fields entirely and just keep the Icons and Labels global fields for your nav bar, awesome!

Example File

Please find attached an example file. This file was used for all the screenshots in this article, and is provided to help you fully understand what is going on in this article, and to let you experiment in FileMaker with this solution.

Download Example File

Example File Extra from Stephen Dolenski

Stephen Dolenski of Ocean West Consulting, Inc. has provided an awesome adaptation of the original example file for this article. In Stephen's adaptation, he has added functionality to allow the navigation bar to toggle between each screens various list & form views, as well as a dashboard view, very cool, and I encourage you to check it out also.

Download Stephen's Modified Example File

Something to say? Post a comment...

Comments

  • Peter Bouma 07/06/2011 8:25am (14 years ago)

    Hi Daniel,

    As always, your solutions are intelligent and efficient, and your article was informative and fun to read. Thanks again!
    I think that in this case, the solution could be even more basic. As I experimented somewhat with your example file, I found that you don't need the extra global calculation fields as intermediaries at all. When I change the fields in your Nav bar to the original globals (Icons and Labels), it still works, without even changing you CF.
    Apparently, the function Get( CalculationRepetitionNumber ) not only applies to calculations inside fields, but also to calculations on layout objects. The formatting condition is enough of a calculation in its own right to know about the CalculationRepetitionNumber of the object it's attached to.
    In your example, it's not even necessary to do a screen refresh, since the layout change already takes care of that. Without the layout change you might need to add a Refresh Window.
    (played with in FMA11/OSX)

    Good luck,
    Peter Bouma, Amsterdam, Netherlands

  • Daniel Wood 07/06/2011 6:39am (14 years ago)

    Hi Tom, I can't remember specifically where I got those icons from, but I quite often use IconsPedia.com for icons, or the icons that come with FM Theme Studio, cheers.

  • Tom Droz 07/06/2011 3:37am (14 years ago)

    Any good source for the nice icons you used?

  • Tom Droz 07/06/2011 3:17am (14 years ago)

    Really nice!

  • Paul Spafford 07/06/2011 2:21am (14 years ago)

    Hey Daniel. Very nice and very thorough -- as always!

RSS feed for comments on this page | RSS feed for all comments

Categories(show all)

Subscribe

Tags