# Field reference

Every field type form2wf renders, with a sample and the data it submits.

## Common properties

| Property | Description |
| --- | --- |
| `id` | Unique id within the form. Required for buttons and row actions to work — always set one (the dashboard generates `field_…` ids). |
| `type` | One of the types below. |
| `name` | Key in the submitted `data`. |
| `label` | Label shown above the input. |
| `placeholder` | Placeholder text. For `subtitle` it is the heading text; for `checkbox`, the text beside the box. |
| `required` | Blocks submission until filled (browser-side check). |
| `colSpan` | How many grid columns the field takes, from `1` (default) up to the form's `columns`, or `"full"` for the whole row. See [multi-column layouts](https://form2wf.com/docs/forms#columns). |
| `newRow` | `true` starts the field on a new row. |
| `colStart` | Column the field starts in (`1` = new row). If earlier fields on the row already use that column, the field moves to the next row. |
| `defaultValue` | Initial value. Supports [templates](https://form2wf.com/docs/templates) such as `{{params.plan}}`. |

## Text inputs: text, email, number, tel, date, url, password

Rendered as `<input type="…">`. Any HTML input type works — the type is passed through — and browsers apply their native validation for `email`, `url` and `number`. All values are submitted as strings.

```
{ "id": "phone", "type": "tel",  "name": "phone", "label": "Phone", "placeholder": "+1 555 0100" }
{ "id": "start", "type": "date", "name": "start_date", "label": "Start date", "required": true }
{ "id": "qty",   "type": "number", "name": "quantity", "label": "Quantity", "defaultValue": "1" }
```

submits:

```
{ "phone": "+1 555 0100", "start_date": "2026-10-01", "quantity": "1" }
```

## textarea

```
{ "id": "msg", "type": "textarea", "name": "message", "label": "Message", "required": true, "placeholder": "How can we help?" }
```

## select

A dropdown whose first entry is an empty “Select an option”. Each option's value equals its label. `defaultValue` selects an exact match.

```
{ "id": "plan", "type": "select", "name": "plan", "label": "Plan",
  "options": ["Starter", "Pro", "Enterprise"], "defaultValue": "{{params.plan}}" }
```

## radio

```
{ "id": "contact", "type": "radio", "name": "contact_by", "label": "Contact me by",
  "options": ["Email", "Phone"], "required": true }
```

## rating

Star rating. Visitors click or drag across the stars, or use the arrow keys (Home or Delete clears it). The value is submitted as a **number**, such as `3.75`; an unrated optional field submits an empty string.

```
{ "id": "score", "type": "rating", "name": "score", "label": "How was your visit?", "required": true,
  "ratingConfig": { "max": 5, "step": 0.25 } }
```

| `ratingConfig` key | Values | Default |
| --- | --- | --- |
| `max` | Number of stars, 1–10 | `5` |
| `step` | `0.25` (quarter stars), `0.5` or `1` | `0.25` |

`defaultValue` sets the starting rating and supports [templates](https://form2wf.com/docs/templates), e.g. `{{data.score}}` to show a stored rating on a data page.

## checkbox

A single checkbox. Checked submits `"true"`; **unchecked is omitted entirely**, so treat a missing key as false in n8n. `defaultValue` of `"true"` starts it checked.

```
{ "id": "tos", "type": "checkbox", "name": "accept_terms", "label": "Terms",
  "placeholder": "I agree to the terms of service", "required": true }
```

submits:

```
{ "accept_terms": "true" }
```

## file

A drag-and-drop zone for one file. When a file is attached the submission is sent as `multipart/form-data` instead of JSON — see [multipart payloads](https://form2wf.com/docs/webhooks#multipart). Limit: 10 MB per file.

```
{ "id": "cv", "type": "file", "name": "resume", "label": "Résumé (PDF)", "required": true }
```

Multipart submissions only carry top-level text values. Don't combine `file` with `object` or `array` fields in the same form — nested values are dropped.

## hidden

Sends a value the visitor doesn't see — ideal for tracking the source page or a record id passed in the URL.

```
{ "id": "src", "type": "hidden", "name": "source", "defaultValue": "{{params.utm_source}}" }
```

## display

Read-only text, usually filled from the [onload response](https://form2wf.com/docs/data-pages#onload). Rendered as plain text (HTML is not interpreted).

```
{ "id": "greet", "type": "display", "label": "Account", "displayValue": "Signed in as {{data.user.name}} ({{data.user.plan}})" }
```

## Layout: subtitle, divider, linebreak

```
{ "id": "h1", "type": "subtitle", "label": "Shipping address" }
{ "id": "hr", "type": "divider" }
{ "id": "br", "type": "linebreak" }
```

`subtitle` renders a section heading, `divider` a horizontal rule, and `linebreak` ends the current row in a [multi-column](https://form2wf.com/docs/forms#columns) layout.

## object

Groups child fields into a nested object. Optionally collapsible, with a preview of chosen child values while collapsed.

```
{
  "id": "addr", "type": "object", "name": "address", "label": "Address",
  "objectConfig": { "collapsible": true, "defaultCollapsed": false, "collapsedPreviewFields": ["city"] },
  "children": [
    { "id": "street", "type": "text", "name": "street", "label": "Street" },
    { "id": "city",   "type": "text", "name": "city",   "label": "City", "required": true },
    { "id": "zip",    "type": "text", "name": "zip",    "label": "Postal code" }
  ]
}
```

submits:

```
{ "address": { "street": "1 Main St", "city": "Oslo", "zip": "0150" } }
```

## array

A repeatable group: visitors add, remove and drag-reorder items. Always shows at least one item.

| `arrayConfig` | Default | Description |
| --- | --- | --- |
| `minItems` | `0` | Items can't be removed below this. |
| `maxItems` | unlimited | The add button stops at this count. |
| `itemLabel` | `"Item {{index}}"` | Heading for each item; `{{index}}` is 1-based. |
| `addButtonLabel` | `"Add Item"` | Text of the add button. |
| `allowReorder` | `true` | Drag handles to reorder items. |
| `collapsedPreviewFields` | `[]` | Child names shown when an item is collapsed. |

```
{
  "id": "people", "type": "array", "name": "attendees", "label": "Attendees",
  "arrayConfig": { "minItems": 1, "maxItems": 10, "itemLabel": "Attendee {{index}}", "addButtonLabel": "Add attendee" },
  "children": [
    { "id": "pname",  "type": "text",  "name": "name",  "label": "Name",  "required": true },
    { "id": "pemail", "type": "email", "name": "email", "label": "Email" }
  ]
}
```

submits:

```
{ "attendees": [ { "name": "Ada", "email": "ada@example.com" }, { "name": "Grace", "email": "" } ] }
```

## table

Shows rows from the onload response, with optional row actions, a search box (`tableSearch`) and pages (`pageSize`). See [Data pages](https://form2wf.com/docs/data-pages#tables).

```
{ "id": "orders", "type": "table", "label": "Recent orders", "dataSource": "orders",
  "tableSearch": true, "pageSize": 20,
  "columns": [ { "field": "number", "label": "Order" }, { "field": "total", "label": "Total" } ] }
```

## markdown

Formatted text across the full width of the form: headings, paragraphs, **bold** and _italic_, lists and task lists, tables, quotes, code blocks, links and images. Use it for instructions, terms, a welcome message, or an answer your workflow writes (an AI summary, an article, a status report). It submits nothing.

```
{ "id": "intro", "type": "markdown",
  "markdown": "## Welcome, {{data.user.name}}\n\nUpload your **2026 receipts** below. We'll email you when we're done." }
```

Or take the text from the onload response with `dataSource`, a plain dot path to a markdown string:

```
{ "id": "answer", "type": "markdown", "label": "Summary", "dataSource": "summary", "maxHeight": 400 }
```

onload returns:

```
{ "data": { "summary": "### Contract review\n\n- **Term:** 24 months\n- **Risk:** auto-renewal clause (section 9)" } }
```

| Property | Meaning |
| --- | --- |
| `markdown` | The text. Supports templates (`{{data.x}}`, `{{params.x}}`). |
| `dataSource` | Path to a markdown string in the onload data. When it has text, it's shown instead of `markdown`. |
| `maxHeight` | Pixels (80+). Taller content scrolls inside the field. |
| `label` | Optional heading above the text. |

HTML inside the markdown is shown as text and never runs. Links may only be `https`, `http`, `mailto`, `tel` or `#anchors`, and open in a new tab; images must be `https` or `http`. That makes it safe to show text that came from visitors or from an AI model.

## nav (menu bar)

A full-width menu that turns a set of forms into an app: each item opens one of your forms in place (or an external page in a new tab), and the item for the form being shown is highlighted. Put the same menu at the top of each form in the app.

```
{ "id": "menu", "type": "nav", "navItems": [
  { "label": "Dashboard",   "form": "portal-home" },
  { "label": "My requests", "form": "portal-requests", "params": { "status": "open" } },
  { "label": "Help",        "url": "https://example.com/help" }
] }
```

`form` is a form slug in your organization; `params` are passed like a navigate link's (`{{params.x}}` in the target form, and in its onload webhook). In the builder, add a **Menu Bar** element and write one item per line: `Label | form-slug` or `Label | https://…`.

## chart

Draws data from the onload response as a bar, line, area, pie or donut chart, or as a single headline number (`indicator`). Charts take the width their column span gives them and redraw when it changes, so they fit a quarter-width cell as well as a full row. Visitors can hover or use the arrow keys for exact values, and a "Show table" link lists every value. Charts submit nothing.

```
{ "id": "sales", "type": "chart", "label": "Sales by month", "colSpan": 2,
  "chartConfig": { "kind": "bar", "dataSource": "sales", "labelKey": "month",
    "series": [ { "key": "online", "label": "Online" }, { "key": "store", "label": "In store" } ],
    "stacked": true, "format": "currency", "currency": "USD" } }
```

onload returns:

```
{ "data": { "sales": [ { "month": "Jan", "online": 12400, "store": 8300 },
                       { "month": "Feb", "online": 13900, "store": 7900 } ] } }
```

| `chartConfig` key | Applies to | Values |
| --- | --- | --- |
| `kind` | all | `bar` (default), `line`, `area`, `pie`, `donut`, `indicator` |
| `dataSource` | all | Dot path to an array in the onload data, like `sales` (not `{{data.sales}}`). Each row is one bar, point or slice. |
| `labelKey` | bar, line, area, pie, donut | Row key for the category or slice name. Default: the first text key. |
| `series` | all | Number keys to plot: `["online"]` or `[{ "key": "online", "label": "Online" }]`. Several series make a grouped or stacked bar chart or a multi-line chart. Default: every number key. Pie and donut use the first; indicator uses it for its trend line. |
| `data` | all | Static rows instead of `dataSource`, for a chart that never changes. |
| `horizontal`, `stacked` | bar | `true` for horizontal bars or stacked series. |
| `valueLabels` | bar | Values at the bar ends (one series, or stacked totals). Default `true`. |
| `smooth`, `markers` | line, area | `smooth: true` curves the line. `markers`: `true` or `false`; by default dots show for up to 12 points. |
| `sliceLabels` | pie, donut | `percent` (default), `value` or `none`. Labels only appear where they fit. |
| `centerLabel` | donut | Text under the total in the hole. Default `Total`. |
| `value` | indicator | A template such as `{{data.visitors}}`. Empty = the last row of `dataSource`. |
| `compareTo`, `compareLabel`, `goodWhen` | indicator | Shows the change as a percentage: `compareTo` is a template or `previous` (the row before the last). `compareLabel` e.g. `vs last month`. `goodWhen`: `up` (default, increases are green), `down` or `none`. |
| `caption` | indicator | A short line under the number. |
| `format` | all | `auto` (default: 1610.01 → 1.6K, 99.6912 → 99.7), `compact` (1.6K), `number` (1,610.01), `percent` (fractions: 0.997 → 99.7%), `currency` ($1,610.01; $48.2K from 10,000). Axes, labels and tooltips use it too. |
| `decimals`, `currency`, `prefix`, `suffix` | all | Fixed decimal places (default automatic); ISO currency code (default `USD`); text before or after every number, e.g. `"suffix": " kg"`. For values already in 0–100, use `"suffix": "%"` instead of `percent`. |
| `palette`, `colors` | all | `theme` (default: your theme's primary colour first), `default`, `vivid`, or `custom` with `colors: ["#2a78d6", "#eb6834"]`. Default and vivid are tested to stay distinguishable with colour blindness. Extra series beyond the palette are not drawn; extra pie slices are combined into "Other". |
| `height` | bar, line, area, pie, donut | Pixels, 120–800. Defaults: 260, pie and donut 240, horizontal bars grow with the rows. |
| `table` | bar, line, area, pie, donut | `false` hides the "Show table" link. |

headline number:

```
{ "id": "visitors", "type": "chart", "label": "Visitors",
  "chartConfig": { "kind": "indicator", "value": "{{data.visitors}}", "compareTo": "{{data.visitorsLastMonth}}",
    "compareLabel": "vs last month" } }
```

## button

Triggers a webhook, opens another form, opens a web page, or goes back. Consecutive buttons and links render in one row. See [Buttons](https://form2wf.com/docs/data-pages#buttons).

```
{ "id": "approve", "type": "button", "label": "Approve", "buttonAction": "webhook", "buttonStyle": "primary",
  "buttonWebhookUrl": "https://n8n.example.com/webhook/approve?id={{params.id}}", "buttonWebhookMethod": "POST" }
{ "id": "open", "type": "button", "label": "Open", "buttonAction": "url",
  "buttonUrl": "https://files.example.com/{{data.file.path}}" }
```

A `url` button opens `buttonUrl` in a new tab, like a link with `linkAction: "url"`. Templates work in it; only `https`, `http`, `mailto` and `tel` URLs open.

## link

```
{ "id": "help", "type": "link", "label": "Pricing details", "linkAction": "url", "linkUrl": "https://example.com/pricing?plan={{params.plan}}" }
{ "id": "next", "type": "link", "label": "Continue to step 2", "linkAction": "navigate",
  "linkTargetForm": "signup-step-2", "linkTargetParams": { "email": "{{params.email}}" } }
```

`linkAction`: `navigate` (default — load another form of yours by slug), `back`, or `url` (opens in a new tab).

## Not supported

Conditional visibility, min/max/pattern validation rules, multi-select dropdowns, and options with separate values and labels. Validate important rules in your n8n workflow.

---
Source: https://form2wf.com/docs/fields — Form2Workflow documentation (Building forms)
