Skip to main content

Multi-Page Forms

Forma supports multi-page wizard-style forms through the pages property. Pages help organize complex forms into manageable steps.

Structure

{
"pages": [
{
"id": "page-id",
"title": "Page Title",
"description": "Optional instructions",
"visibleWhen": "...",
"fields": ["field1", "field2"]
}
]
}

Page Properties

PropertyTypeRequiredDescription
idstringYesUnique page identifier
titlestringYesPage title shown in navigation
descriptionstringNoInstructions or context for the page
visibleWhenstringNoFEEL expression to conditionally show page
fieldsarrayYesField names to display on this page

Basic Example

{
"schema": {
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"email": { "type": "string" },
"phone": { "type": "string" },
"message": { "type": "string" }
}
},
"fields": {
"firstName": { "label": "First Name" },
"lastName": { "label": "Last Name" },
"email": { "label": "Email" },
"phone": { "label": "Phone" },
"message": { "label": "Message", "type": "textarea" }
},
"fieldOrder": ["firstName", "lastName", "email", "phone", "message"],
"pages": [
{
"id": "personal-info",
"title": "Personal Information",
"description": "Please provide your contact details",
"fields": ["firstName", "lastName"]
},
{
"id": "contact",
"title": "Contact Details",
"fields": ["email", "phone"]
},
{
"id": "message",
"title": "Your Message",
"fields": ["message"]
}
]
}

Conditional Pages

Use visibleWhen to show pages based on user input:

{
"pages": [
{
"id": "basic-info",
"title": "Basic Information",
"fields": ["name", "email", "accountType"]
},
{
"id": "business-details",
"title": "Business Details",
"visibleWhen": "accountType = \"business\"",
"fields": ["companyName", "taxId", "industry"]
},
{
"id": "preferences",
"title": "Preferences",
"fields": ["newsletter", "notifications"]
}
]
}

When accountType is not "business", the Business Details page is skipped entirely.

Automatic Navigation

The form renderer handles page navigation automatically:

  • Next advances to the next visible page
  • Previous returns to the previous page
  • Submit appears on the last page

Validation on Navigation

When navigating to the next page:

  • All fields on the current page are validated
  • Navigation is blocked if validation fails
  • Hidden fields are not validated

Page Organization Patterns

Linear Wizard

Simple sequential pages:

{
"pages": [
{ "id": "step-1", "title": "Step 1", "fields": [...] },
{ "id": "step-2", "title": "Step 2", "fields": [...] },
{ "id": "step-3", "title": "Step 3", "fields": [...] }
]
}

Branching Wizard

Different paths based on user choices:

{
"pages": [
{
"id": "select-type",
"title": "Select Type",
"fields": ["applicationType"]
},
{
"id": "individual-details",
"title": "Individual Details",
"visibleWhen": "applicationType = \"individual\"",
"fields": ["ssn", "dateOfBirth"]
},
{
"id": "business-details",
"title": "Business Details",
"visibleWhen": "applicationType = \"business\"",
"fields": ["ein", "incorporationDate"]
},
{
"id": "review",
"title": "Review & Submit",
"fields": ["termsAccepted"]
}
]
}

Grouped Sections

Logical groupings of related information:

{
"pages": [
{
"id": "applicant",
"title": "Applicant Information",
"description": "Tell us about yourself",
"fields": ["fullName", "email", "phone", "address"]
},
{
"id": "employment",
"title": "Employment History",
"description": "Your work experience",
"fields": ["currentEmployer", "jobTitle", "yearsExperience"]
},
{
"id": "education",
"title": "Education",
"description": "Your educational background",
"fields": ["highestDegree", "institution", "graduationYear"]
}
]
}

Field Assignment

Rules

  • Each field in fields must exist in the form's fields object
  • A field should only appear on one page
  • Fields not assigned to any page are not displayed

Handling Conditional Fields

Conditional fields can be assigned to pages, and they'll show/hide based on their visibleWhen:

{
"fields": {
"hasSpouse": { "label": "Are you married?" },
"spouseName": {
"label": "Spouse Name",
"visibleWhen": "hasSpouse = true"
}
},
"pages": [
{
"id": "family",
"title": "Family Information",
"fields": ["hasSpouse", "spouseName"]
}
]
}

Best Practices

  1. Keep pages focused - Each page should cover one topic or section

  2. Use descriptive titles - Help users understand where they are in the process

  3. Add descriptions - Provide context for what information is needed

  4. Order logically - Put dependent questions after their triggers

  5. Limit fields per page - 5-7 fields per page is usually ideal

  6. Show progress - Most form renderers show a progress indicator

  7. Consider conditional pages carefully - Ensure the flow makes sense regardless of which pages are shown