form.json defines what someone fills out: fields, their types, validation rules, and any computed values. Open it from Project Filesform.json.

The editor

The field ID auto-fills from the label (lowercased, spaces → underscores) the first time you type a label; edit the ID directly and it stops auto-following.

Field types

| Type | What it's for | Type-specific options in the editor | |---|---|---| | Text | Free text | Min/max length, regex pattern | | Number | Numeric entry | Min/max value | | Currency | Money entry | Min/max value | | Date | A date | Date format hint | | Dropdown | Pick one of a fixed list | Options list (add/remove chips) | | Checkbox | On/off | - | | File | A photo/file upload | Accept filter (e.g. image/*) | | Signature | Captured signature | - | | Repeating Group | A variable-length list of sub-fields (line items, options, etc.) | See below |

Required (a toggle) and Autocomplete Key (a text field - see Autocomplete below) are available on every applicable type, at the top of the sheet.

format doesn't do anything yet. The date field's "Date format" box and a computed field's format setting are stored but not applied anywhere - there's no built-in currency/date/phone formatter. Do display formatting where the value is actually shown, i.e. in the layout's text blocks (see Block Types Reference), not here.

Repeating groups

A repeating group is a list of rows, each with its own set of sub-fields - the right shape for "add as many line items/options/passengers as needed" instead of a fixed number of similarly-named fields. At fill-out time it renders as an "Add row" list (see Fill Out a Form); in the submitted data it's a list of objects, one per row, keyed by each sub-field's ID.

The editor can create a repeating-group field, but can't yet configure its sub-fields - you'll need to edit form.json directly for that part (open it in the Script Editor - it edits any plain-text file, not just scripts - or any external editor). The shape:

{
  "id": "options",
  "type": "repeating-group",
  "label": "Aftermarket Options",
  "fields": [
    { "id": "description", "type": "text", "label": "Description" },
    { "id": "price", "type": "currency", "label": "Price", "min": 0 }
  ]
}

fields here is a normal array of field definitions, same shape as top-level fields (minus nested repeating groups - one level is as deep as this goes).

Autocomplete

Text, Number, Currency, and Date fields can offer as-you-type suggestions, pulled from that project's autocomplete.json - a plain list of suggested values the form's author curates ahead of time in the Autocomplete Editor, not something that grows from what people type during fill-out.

To wire it up:

  1. Open the Autocomplete Editor and add a key with its list of suggested values - e.g. a make key with a list of car makes.
  2. In this editor, set that field's Autocomplete Key to the same key (e.g. make).

A key can be reused across multiple fields. A field with no Autocomplete Key set (or one that doesn't match anything in autocomplete.json) just doesn't offer suggestions - not an error.

Computed fields

A computed field derives its value from other fields with a formula, evaluated and snapshotted at submit time - not something someone fills in directly. There's no in-app UI for these yet; add them to form.json's computed array by hand:

"computed": [
  { "id": "price_with_tax", "label": "Price + Tax", "expression": "sale_price * 1.08" }
]

Validation reference

| Key | Applies to | Meaning | |---|---|---| | required | any | Must be filled in | | min / max | number, currency | Numeric bounds | | min_length / max_length | text | Character-count bounds | | regex | text | Must match this pattern | | options | dropdown | The picklist | | accept | file | MIME filter, e.g. "image/*" |

Anything beyond these declarative rules - comparing two fields against each other, for example - belongs in validate.js. See Scripting & Processing.