Field types
Level 1 use: a standalone <baht-form>. Type into the form — every keystroke emits
baht-change; the values on the right are the emitted data.
Rendered form <baht-form>
Emitted data baht-change
{}Source fields JSON
{
"form_id": "demo-fields",
"form_name": "Showcase",
"fields": [
{
"order": 0,
"type": "label",
"key": "intro",
"text": "Every control, one JSON.",
"variant": "heading"
},
{
"order": 1,
"type": "text",
"key": "name",
"label": "Text",
"placeholder": "Your name",
"width": "1/2",
"required": true,
"value": ""
},
{
"order": 2,
"type": "email",
"key": "email",
"label": "Email",
"placeholder": "a@b.co",
"width": "1/2",
"value": ""
},
{
"order": 3,
"type": "number",
"key": "age",
"label": "Number",
"width": "1/4",
"min": 0,
"max": 120,
"value": null
},
{
"order": 4,
"type": "date",
"key": "dob",
"label": "Date",
"width": "1/4",
"value": null
},
{
"order": 5,
"type": "dropdown",
"key": "province",
"label": "Dropdown",
"width": "1/2",
"placeholder": "Pick one…",
"options": [
{
"key": "bkk",
"label": "Bangkok"
},
{
"key": "cnx",
"label": "Chiang Mai"
},
{
"key": "hkt",
"label": "Phuket"
}
],
"value": null
},
{
"order": 6,
"type": "radio",
"key": "plan",
"label": "Radio",
"width": "1/2",
"options": [
{
"key": "free",
"label": "Free"
},
{
"key": "pro",
"label": "Pro"
}
],
"value": "free"
},
{
"order": 7,
"type": "multiselect",
"key": "interests",
"label": "Multiselect",
"width": "1/2",
"options": [
{
"key": "forms",
"label": "Forms"
},
{
"key": "flows",
"label": "Workflows"
},
{
"key": "rules",
"label": "Rules"
}
],
"value": []
},
{
"order": 8,
"type": "textarea",
"key": "bio",
"label": "Textarea",
"rows": 3,
"width": "1/2",
"max_length": 200,
"value": ""
},
{
"order": 9,
"type": "checkbox",
"key": "accept",
"label": "Checkbox: accept terms",
"width": "1/2",
"required": true,
"value": false
},
{
"order": 10,
"type": "toggle",
"key": "newsletter",
"label": "Toggle: newsletter",
"width": "1/2",
"value": false
},
{
"order": 11,
"type": "file",
"key": "doc",
"label": "File (capture only)",
"accept": ".pdf,.png",
"width": "full",
"value": null
}
]
}Seventeen field types ship in core: text, textarea, markdown, number, currency, email,
password, dropdown, multiselect, checkbox, radio, toggle, date, file, label,
section and repeater. Each is one entry in fields[] with snake_case keys
(max_length, min_rows, date_mode, …); the per-element pages under Data input show the
same controls used standalone.
Form layout
Section titled “Form layout”layout on the form sets how its fields sit, so no CSS of your own is needed:
{ "form_id": "change", "form_name": "Change", "layout": { "label": "left", "label_width": "200px", "columns": 2 }, "fields": [ { "order": 1, "type": "text", "key": "category", "label": "Category", "column": 1 }, { "order": 2, "type": "text", "key": "requested_by", "label": "Requested by", "column": 2 }, { "order": 3, "type": "text", "key": "summary", "label": "Summary" } ]}With label: 'left' every label takes one width, so they keep one line across the form. With
columns: 2 each column fills on its own, a hidden field leaves no gap, and a field with no column
spans both, below the longer one. Under 720px it all stacks.
Hidden fields
Section titled “Hidden fields”hidden: true keeps a field out of sight and in the data: for a value that only scripts or the host
set, such as what a workflow routes on. It takes no place in the layout, holds no tab open and the form
does not validate it, so do not mark it required.
A rule that hides a field is different. Rules say a field does not apply right now, so the validator
drops its value when the form is checked on the server. Use a rule for that, and hidden for a value
that must arrive.