4.2 Implementing Page Navigation (Actions & Site Navigation UI)
Navigation is a crucial aspect of any BetterForms application. This section covers both programmatic navigation using actions and setting up site-wide navigation menus that users can interact with.
Two Types of Navigation in BetterForms
1. Action-Based Navigation
Navigation triggered by user actions (button clicks, form submissions, etc.)
2. Site Navigation Menu
Persistent navigation menus that appear on all pages (typically in the sidebar)
Action-Based Navigation
Using the path
Action
path
ActionThe path
action is the primary way to navigate between pages programmatically:
{
"action": "path",
"options": {
"path": "/dashboard"
}
}
This action can be used in:
Button actions
Form submissions
Hook responses
Navigation menu items
Navigation Button Examples
Basic Page Navigation
{
"type": "button",
"text": "Go to Dashboard",
"buttonClasses": "btn btn-primary",
"styleClasses": "col-md-4",
"actions": [{
"action": "path",
"options": {
"path": "/dashboard"
}
}]
}
Navigation with Data
Pass data to the destination page using query parameters:
{
"type": "button",
"text": "Edit Contact",
"buttonClasses": "btn btn-info",
"styleClasses": "col-md-4",
"actions": [{
"action": "path",
"options": {
"path": "/contact-edit?id=123&mode=edit"
}
}]
}
External Navigation
Link to external websites:
{
"type": "button",
"text": "Open Documentation",
"buttonClasses": "btn btn-secondary",
"styleClasses": "col-md-4",
"actions": [{
"action": "path",
"options": {
"url": "https://docs.fmbetterforms.com/"
}
}]
}
Save and Navigate Pattern
Common FileMaker developer pattern - save data then navigate:
{
"type": "button",
"text": "Save & Return",
"buttonClasses": "btn btn-success",
"styleClasses": "col-md-4",
"actions": [
{
"action": "runUtilityHook",
"options": {
"type": "save"
}
},
{
"action": "path",
"options": {
"path": "/contact-list"
}
}
]
}
Setting Up Site Navigation in the IDE
Where to Configure Site Navigation
Open App Settings in the BetterForms IDE
Navigate to Environment section
Find the Navigation tab
Configure your navigation schema
Navigation Slugs (URL Mapping)
First, set up navigation slugs to map friendly URLs to page IDs:
{
"default": {
"id": "36D74465-3F11-4CE4-A0FD-370D78C98B86"
},
"dashboard": {
"id": "633D7D10-F8AD-4B6E-8D86-BDC8038D6E91"
},
"contacts": {
"id": "A1B2C3D4-E5F6-7890-1234-567890ABCDEF"
},
"settings": {
"id": "F1E2D3C4-B5A6-9876-5432-10FEDCBA9876"
}
}
Benefits of Navigation Slugs:
Clean URLs:
/dashboard
instead of/form/633D7D10-F8AD-4B6E-8D86-BDC8038D6E91
Easy Updates: Change the page ID in one place to update all references
User-Friendly: URLs are easier to understand and remember
Navigation Menu Schema
The navigation menu is defined as an array of objects in the Menu Schema section:
[{
"sectionLabel": "Main Menu",
"subs": [{
"label": "Dashboard",
"icon": "fa fa-home",
"path": "/dashboard"
}, {
"label": "Contacts",
"icon": "fa fa-users",
"path": "/contacts"
}, {
"label": "Settings",
"icon": "fa fa-cog",
"path": "/settings"
}]
}]
Navigation Menu Structure
Top Level Properties:
sectionLabel
: Section title (not clickable)subs
: Array of menu itemsstyleClassesSection
: CSS classes for the section
Menu Item Properties:
label
: Display texticon
: Font Awesome icon classpath
: Navigation path (corresponds to slugs)actions
: Alternative to path for complex behaviorsvisible
: Boolean orvisible_calc
for conditional display
Advanced Navigation Examples
Dropdown Menus
Create hierarchical navigation with nested menus:
[{
"sectionLabel": "Main Menu",
"subs": [{
"label": "Dashboard",
"icon": "fa fa-home",
"path": "/dashboard"
}, {
"label": "Contacts",
"icon": "fa fa-users",
"subs": [{
"label": "View All Contacts",
"icon": "fa fa-list",
"path": "/contacts"
}, {
"label": "Add New Contact",
"icon": "fa fa-plus",
"path": "/contact-new"
}, {
"divider": true
}, {
"label": "Import Contacts",
"icon": "fa fa-upload",
"path": "/contact-import"
}]
}]
}]
Action-Based Navigation Items
Use actions instead of direct navigation for complex behaviors:
[{
"sectionLabel": "Main Menu",
"subs": [{
"label": "Logout",
"icon": "fa fa-sign-out",
"actions": [{
"action": "authLogout"
}, {
"action": "path",
"options": {
"path": "/login"
}
}]
}]
}]
Conditional Navigation
Show navigation items based on user permissions:
[{
"sectionLabel": "Main Menu",
"subs": [{
"label": "Admin Panel",
"icon": "fa fa-shield",
"path": "/admin",
"visible_calc": "app.user.role === 'admin'"
}]
}]
Navigation with Badges
Add dynamic badges to navigation items:
[{
"sectionLabel": "Main Menu",
"subs": [{
"html": "<a href=\"/#/messages\" title=\"Messages\">\n <i class=\"fa fa-envelope\"></i> Messages\n <span class=\"pull-right badge badge-danger\">{{app.unreadCount}}</span>\n</a>"
}]
}]
URL Structure and Query Parameters
BetterForms URL Structure
https://yourdomain.fmbetterforms.com/#/dashboard?id=123&mode=edit
Components:
https://yourdomain.fmbetterforms.com
- Your domain#/dashboard
- Navigation slug?id=123&mode=edit
- Query parameters
Working with Query Parameters
In FileMaker Scripts: Access query parameters via the $$BF_Query
global variable:
// In your onFormRequest hook
Set Variable $contactId = JSONGetElement($$BF_Query, "id")
Set Variable $mode = JSONGetElement($$BF_Query, "mode")
In JavaScript/HTML:
// Using BetterForms utility function
const contactId = BF.getQueryParam('id');
const mode = BF.getQueryParam('mode');
IDE Navigation Configuration Workflow
Step 1: Plan Your Navigation Structure
List all pages in your app
Group related pages under logical sections
Determine hierarchy (which pages need submenus)
Consider user roles (which pages need conditional access)
Step 2: Set Up Navigation Slugs
Go to App Settings → Navigation
Find the Slug Names section
Add entries for each page:
{ "dashboard": { "id": "your-page-id" }, "contacts": { "id": "your-page-id" }, "settings": { "id": "your-page-id" } }
Step 3: Configure Menu Schema
In the Menu Schema section
Build your navigation structure:
[{ "sectionLabel": "Main Menu", "subs": [ // Your menu items here ] }]
Step 4: Test Navigation
Save your changes
Test each navigation item
Verify paths resolve correctly
Check conditional visibility
Best Practices
1. Consistent Navigation Structure
Keep navigation consistent across all pages
Use familiar icons and terminology
Group related functionality together
2. User-Friendly URLs
Use descriptive navigation slugs
Avoid exposing internal page IDs
Keep URLs short and memorable
3. Responsive Design
Consider mobile navigation experience
Use appropriate icons for touch interfaces
Test navigation on different screen sizes
4. Performance Optimization
Minimize navigation complexity
Use conditional visibility judiciously
Consider caching navigation data
Integration with FileMaker
Navigation-Triggered Scripts
Navigation can trigger FileMaker scripts using actions:
{
"label": "Generate Report",
"icon": "fa fa-file-pdf",
"actions": [{
"action": "runUtilityHook",
"options": {
"type": "generateReport",
"reportType": "monthly"
}
}]
}
Dynamic Navigation Updates
Update navigation based on FileMaker data:
{
"label": "Orders",
"icon": "fa fa-shopping-cart",
"path": "/orders",
"visible_calc": "app.user.permissions.includes('view_orders')"
}
Troubleshooting Common Issues
Navigation Not Working
Check that navigation slugs are properly configured
Verify page IDs are correct
Ensure JSON syntax is valid
Pages Not Loading
Confirm target pages exist
Check page authentication settings
Verify navigation paths match slug names
Conditional Navigation Issues
Test
visible_calc
expressionsVerify app model data is available
Check for JavaScript syntax errors
Next Steps
Now that you understand navigation, you can:
Implement data tables - See 4.3 Displaying Data in Tables
Style your navigation - See 4.4 Basic App Styling
Learn about authentication - See Users & Authentication
Last updated