Controlling Component Visibility

The Visibility System allows you to dynamically show or hide components based on the state of your application. Instead of static forms, you can create reactive interfaces that adapt to user input, user roles, or database records.

How it Works

Every component in the App Builder has a Visibility Logic setting.

  • Default: If left empty, the component is always visible.
  • Logic: If you provide an expression, the system evaluates it.
  • If the result is true, the component is shown.
  • If the result is false, the component is hidden.

Builder vs. Live Mode

  • In the Live App: Hidden components are completely removed from the screen.
  • In the App Builder: To help you design, hidden components are not removed. Instead, they appear semi-transparent with a dashed orange border and a label saying "Hidden by Logic". This ensures you can still edit them even if the logic evaluates to false.

The Syntax

The logic engine uses standard JavaScript comparisons combined with a special Double Curly Brace syntax to access your data.

Accessing Data: {{ ... }}

To read a value from your application, wrap the path in curly braces. The system replaces these tags with the actual values before running the logic.

NamespaceDescriptionExample
pageDataData currently entered in the form inputs on the screen.{{pageData.firstName}}
recordData from the database record currently loaded (if editing).{{record.status}}
systemGlobal app data (User info, Theme, Dates).{{system.user.email}}
paramsValues from the URL (e.g., ID or query strings).{{params.id}}

Comparison Operators

You can use standard logical operators to compare values:

  • == (Equals)
  • != (Does not equal)
  • > (Greater than)
  • && (AND - both must be true)
  • || (OR - at least one must be true)

Utility Functions (utils)

Data can be messy (null values, empty lists, etc.). We provide a built-in utils library to make your logic robust and crash-proof.

1. utils.isEmpty(value)

Checks if a value is effectively "blank". It returns true for: null, undefined, empty strings "", empty arrays [], or empty objects {}.

Use Case: Show a "Submit" button only when an email is typed.

!utils.isEmpty({{pageData.email}})

2. utils.includes(list, item)

Checks if a list contains a specific item, or if a string contains a substring.

Use Case: Show a generic Admin panel only to users with the 'admin' role.

utils.includes({{system.user.roles}}, 'admin')

Use Case: Show a field if the 'Ticket Type' dropdown contains the word "Urgent".

utils.includes({{pageData.ticketType}}, 'Urgent')

3. utils.isAfter(dateA, dateB)

Compares two dates. Returns true if dateA is after dateB.

Use Case: Show an overdue warning if the due date is past today.

utils.isAfter({{system.date.today}}, {{record.dueDate}})

Cookbook: Common Examples

Scenario 1: Conditional Form Fields

Goal: Only show the "Github Username" input if the user selects "Developer" as their Job Title.

  • Logic:
{{pageData.jobTitle}} == 'Developer'

Scenario 2: Edit Mode Only

Goal: Show a "Delete" button only if we are editing an existing record (not creating a new one), and the record has an ID.

  • Logic:
!utils.isEmpty({{record.id}})

Scenario 3: Complex Multi-Condition

Goal: Show a generic "Manager Approval" section if the Total Cost is over $1,000 AND the department is Sales.

  • Logic:
{{pageData.totalCost}} > 1000 && {{pageData.department}} == 'Sales'

Scenario 4: URL Based Visibility

Goal: Show a special specific configuration panel only if the URL contains ?mode=advanced.

  • Logic:
{{params.mode}} == 'advanced'

Troubleshooting

  • Editor Autocomplete: When typing in the Logic Editor, the system will suggest available variables (like pageData or utils). Use these suggestions to avoid typos.
  • Case Sensitivity: "Developer" is not the same as "developer". Ensure your text matches exactly.
  • Null Values: If a field is empty, accessing it might result in undefined. It is safer to use utils.isEmpty({{pageData.field}}) than to check {{pageData.field}} == ''.