Field types
Every field is a subtype of the sealed FormFieldDefinition. A switch over a field is exhaustive, and each subtype's copyWith returns its own concrete type.
Shared options
Every field type accepts these parameters.
| Parameter | Type | Meaning |
|---|---|---|
key | String | Required. Stable value key, unique in the form. Values, rules and formulas ($key) use it. |
label | String | Required, non-blank. |
description | String? | A sentence under the label saying what the field is for. |
hint | String? | Example text inside an empty input. |
helpText | String? | Longer guidance behind the field's info button. |
required | bool | Adds a RequiredValidation at index 0 of validations. The required getter reads it back. |
readOnly | bool | Starts the field disabled. SetEnabled rules can only narrow further. |
validations | Iterable<FormValidation> | Ordered list of rules. See Validation. |
On copyWith, null keeps a text value and a blank string clears description, hint or helpText. copyWith(required: ...) adds or removes only the required rule.
final withHelp = field.copyWith(helpText: 'One line; details go in What happened.');
final optional = field.copyWith(required: false);Built-in types
| Class | JSON type | Own options | Value |
|---|---|---|---|
TextFormField | text | inputKind: TextInputKind (singleLine, multiline, richText, masked); shorthand multiline: true | String |
NumberFormField | number | decimal: bool. Bounds come from NumericRangeValidation. | int, or FormulaNumber when decimal |
MoneyFormField | money | defaultCurrency: String? | MoneyValue(amount, currency) |
QuantityFormField | quantity | dimension: String?, units: Iterable<String> (the first is the default; empty means the host's unit lookup offers them) | QuantityValue(amount, unit) |
DurationFormField | duration | none | Duration |
ToggleFormField | boolean | none | bool |
ChoiceFormField | choice | choices: Iterable<FormChoice> (required), multiple: bool | String, or Set<String> when multiple |
ReferenceFormField | reference | target: String (a host entity type id, required), multiple: bool | record id(s) |
RatingFormField | rating | maxStars: int (default 5, at most 10) | int from 1 to maxStars; null for no rating |
DateTimeFormField | dateTime | kind: TemporalKind (date, time, dateTime); shorthand dateOnly: true | DateTime |
DateRangeFormField | dateRange | none | DateRangeValue(start, end) |
DateTimeRangeFormField | dateTimeRange | none | DateTimeRangeValue(start, end) |
AttachmentFormField | attachment | imagesOnly: bool, multiple: bool | List<AttachmentValue> |
FormulaFormField | formula | expression: String, outputType: FormulaType (both required). Always read-only; has no required or readOnly parameter. | computed |
CustomFormField<T> | your typeId | typeId, configuration: T, configurationVersion (default 1) | yours |
Minimum sizes for each type are listed on the Layout page.
Choices
ChoiceFormField(
key: 'severity',
label: 'Severity',
required: true,
choices: const [
FormChoice(value: 'minor', label: 'Minor'),
FormChoice(value: 'major', label: 'Major'),
FormChoice(value: 'critical', label: 'Critical'),
],
)Choice values must be non-blank and unique; labels must be non-blank.
Host services
Some types need the host to look things up. FormView takes a callback for each:
| Field | FormView parameter | Signature |
|---|---|---|
ReferenceFormField | referenceSearch | Future<List<FormChoice>> Function(String target, String query, int pageSize) |
ReferenceFormField | referenceLabel | Future<String?> Function(String target, String value) |
MoneyFormField, QuantityFormField | codeSearch | Future<List<FormChoice>> Function(String catalog, String? dimension, String query, int pageSize) (catalog is currency or unit) |
AttachmentFormField | attachmentPicker | Future<List<AttachmentValue>?> Function(AttachmentFormField field, List<AttachmentValue> current); null when the user cancels |
CustomFormField | customBuilder | Widget Function(BuildContext, FormFieldDefinition field, Object? value, ValueChanged<Object?> onChanged) |
Formula fields
FormulaFormField(
key: 'line_cost',
label: 'Line cost',
expression: r'$qty * $unit_cost',
outputType: FormulaType.number, // from package:cdx_formula
)A formula declares no dependency list: its inputs come from compiling the expression against the fields in its scope. See Rules and formulas.
Content nodes
Content is not a field and has no value. It sits in the layout tree wherever a field slot can.
| Class | JSON type | Options | Rendered by |
|---|---|---|---|
HeadingContent | heading | text, level (1 to 6, default 2) | FormView |
TextContent | text | text, formatted: bool | FormView |
CalloutContent | callout | text | FormView |
DividerContent | divider | none | FormView |
SpacerContent | spacer | gridUnits (at least 1) | FormView |
ImageContent | image | assetReference, altText (both non-blank) | FormView(assetBuilder:) |
DataDisplayContent | dataDisplay | sourceId, style: DataDisplayStyle (keyValue, table) | FormView(dataDisplayBuilder:) |
CustomContent<T> | custom | typeId, configuration: T, configurationVersion | No renderer yet: FormView shows an "Unsupported content" placeholder |
Coming later
Text formats (email, phone, URL) with implicit validation, input masks, sliders, attachment limits passed to the picker, and per-type presentation variants (choice as radio or chips, toggle as checkbox) are planned. See the Roadmap.