
Field properties
Fields are configurable using the following properties:| Property | Required | Type | Description |
|---|---|---|---|
| type | Yes | string | Field type: Boolean, Date, Dateonly, Enum, Json, Number, NumberList, EnumList, String, StringList, File, FileList, Collection |
| label | Yes | string | Label displayed to the user |
| id | No | string | Internal identifier. If not set, the label is used. Use this to access values in context.formValues |
| description | No | string | Help text displayed below the field |
| isRequired | No | boolean | Make the field required (default: false) |
| defaultValue | No | any | Default value pre-filled in the form |
| isReadOnly | No | boolean | Make the field read-only (default: false) |
| enumValues | Required for Enum | string[] | List of possible values when type is Enum |
| widget | No | string | UI widget to use (see widgets section below) |
Basic form example
Field types
String
Text input for short strings.TextArea widget for longer text:
Number
Numeric input with optional constraints.Boolean
Checkbox for true/false values.Date and Dateonly
Date picker for dates with or without time.Enum
Dropdown with predefined options.Collection
Reference to a record from another collection.
File and FileList
File upload fields.Lists
Arrays of values.Dynamic forms
Make forms reactive by using functions instead of static values. Functions receive the action context and access form values and selected records.Dynamic required fields
Make a field required based on another field’s value:Conditional visibility
Show or hide fields based on conditions:Default values from record data
Pre-fill form with data from the selected record:Dynamic enum values
Change dropdown options based on context:Dynamic collection references
Change the target collection dynamically:Widgets
Widgets customize the UI appearance of fields. Here are the most common ones:TextArea
Multi-line text input.
TextInput
One-line text input, the default widget forString fields.

TextInputList
One-line text input to enter a list of string values.
AddressAutocomplete
Text input with address autocomplete powered by the Google Maps API.

Checkbox
Single checkbox for boolean values.
Dropdown
Alternative to Enum for dropdown selection.
RadioGroup
Radio buttons for single selection.
CheckboxGroup
Checkboxes for multiple selection.DatePicker
Calendar widget for date selection.TimePicker
Input for entering a time value.
ColorPicker
Color selection widget.FilePicker
File upload with preview.
JsonEditor
JSON editor with syntax highlighting.
UserDropdown
Dropdown pre-filled with Forest users.
CurrencyInput
Number input with currency formatting.
RichText
Rich text editor with formatting options.
Advanced patterns
Multi-step forms
Create wizard-like forms by conditionally showing sections:Read-only fields for context
Show record data as read-only context:Validation with required fields
Combine conditions for complex validation:Accessing form values
In the execute handler, access form values from the context:Layout components
Organize your fields with layout components, separators, rows, HTML blocks, and multi-page forms. Useful when a form has many fields and you want to break it into manageable chunks.Common properties
| Property | Required | Value | Description |
|---|---|---|---|
| type | Yes | "Layout" | Differentiates a layout element from a field |
| component | Yes | "Separator", "Row", "HtmlBlock", "Page" | The layout component to render |
| if (Node.js) / if_condition (Ruby) | No | callable | Only display if the function returns true |
Separator
A horizontal line between two form elements.
HTML block
Render arbitrary HTML content inside a form, useful for instructions, embedded content, or rich formatting.| Property | Required | Value | Description |
|---|---|---|---|
| component | Yes | "HtmlBlock" | Enables this component |
| content | Yes | string or callable returning a string | HTML content to render |

Row
Display two fields side by side on the same line.| Property | Required | Value | Description |
|---|---|---|---|
| component | Yes | "Row" | Enables this component |
| fields | Yes | array of two fields | The two fields to display side by side. No nested layout elements allowed. |

Multi-page form
Break a long form into multiple pages, with next/previous navigation.| Property | Required | Value | Description |
|---|---|---|---|
| component | Yes | "Page" | Enables this component |
| elements | Yes | array of fields and layout elements | Fields and layouts shown on this page |
| nextButtonLabel (Node.js) / next_button_label (Ruby) | No | string | Label for the next button |
| previousButtonLabel (Node.js) / previous_button_label (Ruby) | No | string | Label for the previous button |


If every element on a page is hidden by
if conditions, the page is automatically removed. To prevent this, add an unconditional HtmlBlock explaining why the page is empty.