Browser Navigation

by Paul Jansen

BrowserNavMain

Overview

BrowserNav adds web browser like layout navigation history and requires a single script, one custom function (Optional) and back and forward buttons.  Once the script and custom function have been added to your file, just paste the back and forward buttons onto each layout you wish to include in the navigation history and you’re done.  This module has been designed to be really easy to retrofit to existing solutions; deciding where to put the buttons on your layouts will probably be the most difficult part of the implementation!

There are now three versions:

  • BrowserNav for FileMaker 16 incorporates the following changes:
    1. Rewritten to use the new native JSON functions, BrowserNav now uses only a single global variable.
    2. The actual navigation now uses Layout Number rather than Layout Name to avoid issues when multiple layouts have the same name.
    3. Both single and multiple windows are supported, the latter with either individual or shared history.
  • BrowserNav Multiple Windows obviously added support for multiple windows for FileMaker pre version 16.
  • BrowserNav Single Windows is the original version for FileMaker pre version 16

All versions now have the option to turn off the saving of layouts to the history; this gives more control when running scripted processes that may move through several layouts.

To upgrade to BrowserNav for FileMaker 16, just replace the contents of the custom functions: BrowserNav.SaveNavHistory and BrowserNav.Tooltip.

Features

  • Very easy to retrofit to existing solutions
  • Works with scripted and native layout navigation
  • Back and forward buttons show tooltip of destination layout
  • Button arrows grey if no-where to go
  • History ignores layouts with no back and forward buttons (scripts going to developer layouts for example)
  • Toggle history saving with a global variable
  • No duplicate entries if the layout refreshed
  • Separate button and button text layout objects for easy customisation
  • Central customisation of Tooltips
  • Layout 1 now uses a FileMaker Button Bar for the navigation buttons (added 23.12.2015)

Dependencies

None.  I encourage you to use the version with the custom functions unless you do not have access to FileMaker Pro Advanced.  This allows the save history function and tooltips the be easily modified in one place even if the solution has a large number of layouts with the navigation buttons.  The latest change is a great example of this.  Adding the ability to toggle the saving of layouts requires only a change to the ‘Save’ custom function regardless of how many layouts the navigation has been added to.

License

Completely Free!

Download

The link to download the latest versions is….

BrowserNav Downloads

I do hope it’s useful.

 

What’s Next?

I am planning to add the option to include the the ability to return to the most recently viewed record with each entry in the history.  It seems that there are a number of possible scenarios so any and all input is welcome…

 

72 responses to “Browser Navigation”

  1. Bob Ellis says:

    Simply brilliant. Thank you for the contribution.

    • Paul Jansen says:

      Thanks. I am very pleased with this module; it was worth the effort to get it right. I love the fact it has so few components and is so easy to add to a solution. Trouble is I feel I have set myself a high bar for any future submissions!

  2. Geoff Ryle says:

    Well done, Paul. Thank you!

  3. Chris says:

    Awesome! Already implementing into client solutions!
    Thank you Paul. You’ve set the bar for us all!

  4. Simon Plint says:

    Paul, I agree with the others. Thanks.

    So few moving parts that it took me a while to figure out how it was being done. Magic? No, just conditional formatting.

    This is a great site, I already have a proof of concept solution using Browser Naigation, Master Detail and Navigation, just need a module to handle tab switching now 🙂

    • Paul Jansen says:

      You mention ‘tab switching’ – Do you mean restoring the last tab state when returning to a layout? If so I have a technique I have using with the BrowserNav. It is a variation on someone else’s work, so I need to get permission before submitting it as a module.

      • Tobias Sjögren says:

        Hi Paul, great module!
        I read your reply about tab switching which is what I’m been thinking of as a complement to the module. I’m very interested in the technique that you use with BrowserNav – can you share?
        Also, I use the Single window version – is there any known bugs or problems with the multiple window version?

        • Paul Jansen says:

          Thanks. The technique really quite straightforward. One of the navigation buttons has conditional formatting applied which references a custom function to add the current layout to the history. I chose this method rather than using the “on layout load” trigger as it makes retrofitting to an existing solution easier and works with more versions of FileMaker. The demo file primarily uses the custom function method, but the second layout has the whole calculation within the conditional formatting. The best way to understand it is to download the demo and take it apart, there really isn’t that much to it.

          • Tobias Sjögren says:

            What I meant was the ‘tab switching’ technique where you’re “restoring the last tab state when returning to a layout” as you mentioned – not the BrowserNav module itself. That is what I want to…
            Do you use the multiple window version yourself?

          • Paul Jansen says:

            As most of my clients have used Windows rather than Mac, and I always run database windows maximised within the application window, I don’t have much call for the multi window implementation. I don’t believe that there are any issues with the multi window version, in fact it should really be the default as it can manage both single and multi window scenarios.

            Regarding the tab save and restore, I currently favour the implementation found on this site http://www.modularfilemaker.org/module/restore-tabs/ which can work perfectly well with the Browser Nav module. My view is that keeping them as separate modules helps maintain simplicity.

          • Tobias Sjögren says:

            Paul,

            didn’t see a reply button under your last comment so I write here…
            Thanks for Restore Tabs, seems to be good although I can’t get it to fully work…
            Will try the multiple window BrowserNav version soon!

          • Tobias Sjögren says:

            I have the single window module in my solution and now I try the multiple version which gives me unpredictable results – is it possible to have both versions side by side in the same FM file or do they interfere with each other?

            I don’t want to remove the single window version until I can confirm that the multiple one functions the way I want it to do.

          • Paul Jansen says:

            I think you will definitely have problems with trying to use both versions together for a couple of reasons

            The custom functions for both versions are named the same.

            The variable used to store the history for the single window version is the same as that used for the first window in the multi-window version.

            To migrate from one version to another just replace the contents of the scripts and custom functions. I don’t believe any changes are required to the layout objects.

            You can set the multi window version to behave as the single window version if you want – by having a single history that spans multiple windows as opposed to individual histories for each window.

            Hope this helps

          • Tobias Sjögren says:

            I’ve switched to the multiple window version now, works just fine.
            The only thing is that I have to get rid of my OnLayoutEnter script step that changes the window name (to the LayoutTabelName) to have it working, but it’s not that important anyway. Thanks again!

    • Paul Jansen says:

      No magic involved :). The buttons must be present on each layout and using conditional formatting to trigger the ‘save layout’ process was key to making the module easy to retrofit to existing solutions. I wanted to avoid onLayoutEntry triggers as this would be more work to integrate, especially in complex solutions.

  5. Paul,

    Do you have any intentions of making the Browser Navigation work in a multi-window environment?

    • Paul Jansen says:

      I did consider this, but most of my solutions are single window with the occasional popup that would not be in the history anyway.

      It could be extended to give each window it’s own history – I have a good idea how I would approach this, but I have not looked in detail. Also, for the initial release I wanted to keep it simple.

      Whichever approach is taken, it would need a clean install of the navigation buttons to each layout. 🙁

      • Paul Jansen says:

        Been thinking some more about this. A multi window implementation would have to use the window name as part of the variable name space. This could be problematic as it is possible to both change the window name and have duplicate names.

        It is possible to support multiple windows, but it would be dependent on the developer ensuring that window names not changing after the first history entry has been made and the avoidance of duplicate window names.

        I think I will look at updating the module with caveats when using multiple windows.

    • Paul Jansen says:

      I have added support for multiple windows as well as the option to toggle the saving of layouts to the history by setting a global variable.

  6. David Harris says:

    Thanks so much for your work and making it available! I’m using it in an iPad inventory solution. I really appreciate it!

  7. Dave Dennis says:

    I’m trying to implement this on a project that is using an image as a button. FM 12 allows us to have different button states using the background colour of an image object. Very neat BUT there is no Conditional Formatting on the button object. Given that I have no “text” item to trigger the custom function it’s not working.

    So please indulge my ignorance, but why is the custom function in the conditional formatting and not just another step in the script? I don’t understand the logic.

    • Dave Dennis says:

      I think I get it now. It is behaving like a layout script trigger. Is that it? Just something that loads with every new layout?

      • Paul Jansen says:

        You are correct, the ‘save’ is triggered on any layout you wish to include in the history. Using conditional formatting on the button makes adding this to layouts really quick and doesn’t mess with anything else and has no actual formatting associated with it. The call save the layout could be put in an ‘on layout load’ triggered script if you prefer. I found that I could design/modify the navigation button set and then just paste onto each layout without the requirement for each layout to have an ‘On Load’ trigger. You can add the conditional formatting to a button even if there is no text to format!

  8. mike parsons says:

    Yep add me to the list of happy downloaders! I made my own solution for this years ago using a seperate history table and just adding set field scripts but this is much much simpler.
    Tabs are the last thing to add as most of my solutions have more than one tab set per page so you’d need to track a bit more than just getcurrenttab I suspect the simplest way is a variable per tab set that just gets updated one each tab change.

    Once agin though, tidiest implementation of brower navigation I’ve seen yet.

    best regards

    Mike

    • Paul Jansen says:

      Thanks.

      I have used StickyTabs in the past, but now favour the Restore Tabs module on this site. The two can work well together.

  9. Sandy says:

    This is VERY brilliant! It is as close to Zen as you can get without actually being a monk.
    Thanks

    • Paul Jansen says:

      You are too kind. I must admit to being very pleased with how this turned out. My problem now is that I want all my ‘modules’ to be of the same standard!

  10. Paul,

    Awesome pain free module. Thanks!

  11. Don Clark says:

    Love it! I use Seedcode’s original navigation in some solutions, and it still works well, but is not modular. Thanks for sharing!

  12. […] Browser Navigation – Modular FileMaker. […]

  13. Dave Hobson says:

    Really excellent. Thanks so much for sharing this!
    Dave.

  14. Nate D. says:

    This module looks very promising! Question though: it’s not clear to me how the two initial global variables get set… Was thinking it had to be via File Options > Script Triggers, but I don’t see anything there. What am I missing?

    • Paul Jansen says:

      The back and forward buttons must be present on each layout as they are using conditional formatting to trigger the ‘save layout’ process which was key to making the module easy to retrofit to existing solutions. I wanted to avoid onLayoutEntry triggers as this would be more work to integrate, especially in complex solutions.

  15. Tom R. says:

    Hi,

    I’m afraid I’m having trouble implementing the module. I’m running FMP Advanced 13. I imported the module scripts and the custom function, and copied the buttons from Layout 1 of the BrowserNav file into the relevant layouts of my solution. However, the buttons aren’t working. Initially when you mouse over a button, the cursor changes to a hand; but once you click, nothing happens and the cursor remains a pointer when you mouse over again.

    Maybe I’m missing something obvious; but any advice would be appreciated.

    Thanks!

    • Paul Jansen says:

      Each layout needs one object with the conditional formatting formula

      BrowserNav.SaveNavHistory

      It is this that stores the history.

      The buttons should have the script ‘Browser nav’ attached with the parameter ‘Forward’ or ‘Backward’

      I would check the data viewer to see if a history is actually being recorded as shown in the demo file.

      Hope this is helpful…

  16. Tom R. says:

    P.S. I forgot to mention that the file for my solution is running on FMP Server 13, not the local machine.

    • Paul Jansen says:

      Running on server should make no difference. The history is stored in global variables. You can check the history variables and see iff it is being added to when you manually switch layouts

      I’d suggest stripping out the layout objects and adding then again. (assuming the scripts and custom function are correct.)

  17. Mark B says:

    Great work thanks! I’ve been looking for something that’s easy to implement into my solutions for ages.

  18. Fabrizio says:

    a little problem , on iPad where i have two format to manage Horizontal and Vertical size when fire trigger OnLayoutSizeChange
    i want register only one layout navigation while change the size ..

    Any suggestion ?

    • Paul Jansen says:

      I think it should just work with rotation as the module is set up to prevent double adjacent entries of the same layout.

      If your trigger actually switches layout, you might have a problem. I will need to give this some thought.

  19. Hans Lijnbach says:

    Thanks for the beautiful tool. Works great!

  20. Si B says:

    This looks great but unfortunately I am not using Filmmaker Advanced, is there any chance of a few quick pointers to getting it to work without being able to import the custom function?

    I am quite new to filemaker and may be missing something fundamentally obvious!

    Many thanks in Advance

  21. Paul Jansen says:

    If you look at layout 2 in the example file you will find the technique implemented without custom functions.

  22. Si B says:

    Ah ha! I need to learn to read! Thank you Paul, Awesome work.

  23. Karsten says:

    Paul

    A wonderful module – I could easily integrate it with my own navigation. In one of the comments you mention a way to include the tabs. For a customer I am looking into a method to include the ActiveLayoutObjectName, to improve usability on more complex layouts. Is that something you can provide? I assume it must be included in the list and and the custom function.

    Any feedback much appreciated!
    Karsten

  24. Richard Goldblatt says:

    What an Absolutely brilliant solution, took me a while to work out which bits went where but its just superb, Thanks so much!

  25. Judi McCarthy says:

    Awesome! Elegant! Simple! Free! A thousand times Thank You. No problem importing the pieces, and not only does it work in my solution, the added benefit is that I will learn from it.

  26. Excellent! Thanks so much for posting this elegant solution. This is the nicest browser like navigation implementation I’ve seen. As Judi above me said, it is a great learning tool as well.!!

  27. Jim Medema says:

    Paul,
    Thank you again for your contributions to Modular FileMaker! I’m having some difficulty with implementation and wondered if you knew what I had missed. Here’s my scenario:

    First, I followed your instructions and copied your the buttons from your download file and pasted them on several layouts. All worked as advertised. However, for interface consistency I wanted to take advantage of button icons available in FM14.

    I created two new buttons (using the “Button” tool at the top and not just the rounded rectangle as you did) and set up the Normal, Hover and Pressed states for button and button icon in the Appearance tab. I also copied/pasted the appropriate Tooltip to each button to trigger the updates to the $$Browser…. variable and assigned the script to each button. The new buttons don’t work. Here’s what I’ve done and discovered in my trouble-shooting:

    (1) I placed two text boxes on a few layouts for the $$BrowserNav.Layout.backward and $$BrowserNav.Layout.forward so I could view each global variable. When using my new buttons the global variables remained empty. When simply moved your original buttons onto the layout the variables populated per normal.

    (2) It appears that if the button and the “” text objects are separate objects then the $$ variables populate correctly. When I used the button tool with the icon the $$ did not populate at all.

    Any help or ideas would be appreciated!

    Much thanks,

    Jim

    • Paul Jansen says:

      The magic is in the conditional formatting on the text of the back button. You could put this in the OnLayoutLoad script if you prefer. The key component is a call to the custom function

      BrowserNav.SaveNavHistory

      The reason I used the conditional formatting was to make it really easy to retofit to and existing solution.

      I haven’t had time to consider the best way to update the module to use the new button bar object, but I will give it some thought…

  28. Paul Jansen says:

    The downloads have now been updated to use a Button Bar instead of the separate button and text objects. Having only a single object to paste on to each layout further simplifies the implementation.

  29. Mer says:

    Hi,
    This is just great. Thank you for sharing. Is there an Option to also to use this when I navigate within a single table and then go back to the respective record I was on (at the moment, I am only jumping between different layouts but I when I go from record 1 to 15 to 4 to 7, I would also would like this to be included in the history).
    Best
    Mer

    • Paul Jansen says:

      Thanks.

      I have considered adding a record history as well, but it would add significant complexity to the implementation. In order to include a record history the history would need to know the uuid/serial field for each layout’s table and for this to be robust I think this would require editing a layout object on each layout to be included in the history. I’ve not had enough time to look into this sufficiently to decide if it is worth doing.

    • Paul Jansen says:

      On further reflection, I am not convinced that this would be a good idea as returning to a specific record would inevitably change the found set which to my mind would be undesirable in many scenarios. This could be implemented, but it is not a high priority for me.

      Sorry

  30. Robert Lee says:

    Hi

    I implemented the buttons but unfortunately they don`t work.
    just wondering, is it because my slution consists of many tables, (i see the demo consists of only one table)
    another question my solution was originally designed for PRO therfore was designed that every related record displays in a new window, however now i have users that use it on webdirect and therefore all is on one window, would your button still be able to go back to previous record.

    • Paul Jansen says:

      This module only navigates layouts not records. The history is recorded per window not across multiple windows. From what you describe, I don’t think this module is appropriate for your solution.

  31. “Can Filemaker Do Back Buttons?” said the client.
    “Yes, but the last time I did it, it was a bit of a pain, and pretty clunky to implement” said I.
    Then I found this page, and all of a sudden my world changed.
    This is really excellent!

  32. Bill Gordon says:

    Paul –

    I am somewhat embarrassed to admit that I do not understand how this works. I am something of a newer developer and unfortunately your downloaded module will not let me under the covers. I keep getting the dialog telling me “This action cannot be performed because this file is not modifiable.” Can you help me figure out how to be able to look at the workings of your very clever module?

  33. Paul Jansen says:

    It sounds like you are trying to make changes to the database while it is still inside the zip file. I would suggest copying the sample database to a different location where, hopefully, all will work as expected.

  34. Rob Wyatt says:

    Hi Paul. Just ran across BrowserNav. Fantastic!!! Thank you for sharing it with us. I wanted to echo the comment made by Mer back in January. For my purposes I only need a back button, but it’s essential that I go back to the record as well as the layout. I read your response about the found set and can appreciate that concern. However, my solution is more app-like and doesn’t require the user to enter the Find Mode very often. Toolbars are hidden on every layout.

    The user never sees the previous/next record buttons or the number of found records except on specific List views, which would be the root layouts as far as BrowserNav is concerned (no back button). Since these layouts are the only ones where the user might change the found set, I could live with the found set being changed as the user navigates. Worst case, the user gets back to a list view and the found set has changed and the user must re-do a search. It’s either that or have the user click the back button but not go back to the record he or she expects, just the layout, which I think is more problematic.

    I have implemented BrowserNav in my solution and it works great. Now I’m trying to figure out whether I should try to change my UI to account for the fact that BrowserNav only remembers layouts and not records, or try to customize BrowserNav to also record the unique serial number field value for each of my tables and restore the record when the user clicks the back button. I was hoping you might be able to offer some advice on how to customize it since it sounds like you gave the idea some thought. I appreciate that you don’t want to take it in that direction and would like to give it a try myself, but wanted to ask for any guidance you might care to offer before I make an attempt.

    On another note, I was wondering if you have any suggestions for clearing the appropriate BrowserNav variables when a window is closed (in a multi-window solution). I have a script that runs on every window close in order to take care of a few housekeeping items for certain records. Shouldn’t it be possible to clear the BrowserNav variables for that window when it is closed? In addition to wanting to clear out unused variables, I also want to avoid the situation where Filemaker gives a new window the same name as a window that has been closed and that new window inherits an old BrowserNav history.

    Again, thanks so much for sharing this fantastic solution!

  35. Paul Jansen says:

    Rob,

    Whilst I believe it would be reasonably straightforward to implement remembering the ID of the current record in the history, there is an issue of what to do with layouts having a list view where reconstructing a found set could be complex. One possible option would be to use separate TOs for lists and form views, so that the found sets would not be disrupted when finding the specific record appropriate to the history entry. It would also me necessary to decide what to do about navigating through a found set in form view – store multiple entries for the layout each with a different record ID, store the found set, sort order and last selected record, or a combination of both. It really depends on the usage patterns of an individual solution.

    In my opinion, there is no generic solution and I think this would need to be a custom version of the BrowserNav module.

  36. Paul Jansen says:

    Regarding the close window issue, I have updated the Multi Window version to clear the global variables using an OnWindowClose trigger. Hope this is useful.

  37. Rob Wyatt says:

    Hey Paul, thanks for the OnWindowClose function. You’re awesome! Works great and solves one of the two issues I’ve been having. Regarding restoring a record, I agree that any solution will need to be customized. For my purposes, your idea to make list views a different TO should solve my problem. My users can only search from the list view. Once they have their list of records, they can select a record and just to various related records from there, but they are never in the find mode. So making the list view a different TO should allow the found set to remain in tact. Great idea. I’m going to see how far I get… Thanks again!

  38. Rob Wyatt says:

    Hey Paul, thanks for the OnWindowClose function. You’re awesome! Works great and solves one of the two issues I’ve been having. Regarding restoring a record, I agree that any solution will need to be customized. For my purposes, your idea to make list views a different TO should solve my problem. My users can only search from the list view. Once they have their list of records, they can select a record and jump to various related records from there, but they are never in the find mode. So making the list view a different TO should allow the found set to remain in tact. Great idea. I’m going to see how far I get… Thanks again!

  39. Viss says:

    Hey guys, first off, absolutely love this module. Got a weird behavioral quirk that I’m not sure how to completely remove, explained below.

    Was wondering if any of you have ever run into an odd sporadic issue where layout navigation history isn’t always saved. Specifically, I’ve isolated it to when using GTRR: the target layout doesn’t always trigger the BrowserNav.SaveNavHistory CF via the conditional formatting calc on object when it loads up. It takes an extra back and forward step to get it to start working, but once it kicks in it works everywhere for all GTRR steps for the rest of that user’s session. It’s happened on multiple machines (Server 15, Client OSX FMP15) for different users and causes some confusion as the user is taken back to their layout from two actions ago rather than their previous layout.

    Thanks!

    • Paul Jansen says:

      Viss,

      I have not encountered this issue, so do not have a definitive answer.

      You could try moving the CF call to a hide calculation which returns false and see if this improves reliability, or try moving the CF call to an onLayoutLoad trigger script.

  40. Viss says:

    Thanks for the quick response, Paul. When I get a chance I’ll try moving the CF call to see if it improves reliability and will report back if anything changes. Was hoping not to have to hit up all of the layouts again, but it shouldn’t take too terribly long.

    • Paul Jansen says:

      Viss,

      Did you ever resolve your issue with BrowserNav occasionally failing to save a layout to the history?

  41. Paul (good name isn’t it :D),

    Thank you so much for making this free and so easy to implement and use. I have been having headaches getting something set up that my users would actually enjoy. I have a hunch that they are going to love these back and forward buttons. I have no issues, it’s working perfectly. I just wanted to thank you.

    Sincerely,
    Paul

  42. Peter Boyce says:

    Thank you so much. A very elegant solution, that slotted into a complex navigation system seamlessly.
    Truely awesome.

Leave a Reply

Your email address will not be published. Required fields are marked *