Field Types
Summary
Every field your server sends has a type that tells the client how to render it and what input to accept. This page covers all field types — what JSON to produce and what behavior the client applies.
Type-driven behavior
The client derives all behavior from the field type and structural properties. You do not declare per-field behavior. Set the type, and the client knows what to do.
The context-dependent shortcut (Ctrl+Enter and its alternates Shift+Enter, F6, Ctrl+O) resolves differently depending on field type:
| Field Type | Enter | Ctrl+Enter (and alternates) | Space | Free-text edit |
|---|---|---|---|---|
| Boolean | Advance | — | Toggle | No |
| Option | Advance | Open modal | Cycle | No |
Non-editable with lookup | DrillDown | DrillDown | — | No |
Editable with lookup | Advance | Lookup | — | Yes |
| Editable (no lookup) | Advance | — | — | No |
| TextArea | Advance | Insert newline | — | Yes |
| Read-only | — | — | — | No |
Text
Free text input. The default field type.
json
{
"id": "name",
"label": "Name",
"type": "Text",
"value": "Acme Corp"
}For code fields (uppercase identifiers like customer numbers, product codes), use Text with an input mask:
json
{
"id": "customer_no",
"label": "Customer No.",
"type": "Text",
"value": "10000",
"validation": {
"input_mask": "uppercase",
"max_length": 20
}
}Decimal
Numbers with decimal places. Right-aligned by the client.
json
{
"id": "unit_price",
"label": "Unit Price",
"type": "Decimal",
"value": "1,495.00"
}- Format the value string yourself (thousand separators, decimal places)
- The client accepts:
0-9,.,,,- - On save, the client sends the raw edited string; your server parses it
json
{
"id": "amount",
"label": "Amount",
"type": "Decimal",
"value": "45,000.00",
"validation": {
"min": 0,
"max": 999999.99,
"decimals": 2
}
}Integer
Whole numbers. Right-aligned.
json
{
"id": "line_no",
"label": "Line No.",
"type": "Integer",
"value": "10000"
}The client accepts: 0-9, -
Date
Date input with Navision-style shorthand parsing.
json
{
"id": "posting_date",
"label": "Posting Date",
"type": "Date",
"value": "10-03-2026"
}Format the value according to your
locale.date_formatThe client parses shortcuts:
Shorthand Meaning tToday (work date) t+N/t-NN days after/before today DDDay DD in the current month DDMMDay DD, month MM in current year DDMMYYFull short date The date format (DD-MM-YYYY or MM-DD-YYYY) is controlled by
locale.date_formatin the ScreenContract
Time
24-hour clock. The client auto-corrects separators (, and . become :).
json
{
"id": "start_time",
"label": "Start Time",
"type": "Time",
"value": "08:30:00"
}The client parses shortcuts: t = now, 830 = 08:30:00, 1430 = 14:30:00
Email, Phone, URL
Text fields for contact information. Ctrl+Enter opens the value in the system app (email client, phone dialer, or browser).
json
{
"id": "email",
"label": "E-Mail",
"type": "Email",
"value": "ap@acme.example",
"validation": {
"pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
}
}
{
"id": "phone",
"label": "Phone",
"type": "Phone",
"value": "+45 70 10 20 30"
}
{
"id": "home_page",
"label": "Web",
"type": "URL",
"value": "www.acme.example"
}Boolean
Two-state toggle. Renders as plain text — "Yes" or "No" by default.
json
{
"id": "taxable",
"label": "Taxable",
"type": "Boolean",
"value": "true"
}- Value is always the string
"true"or"false" - Space toggles the value. Enter advances to the next field without toggling
- No edit mode — just toggles
- The bottom bar shows "Space Toggle" when this field is focused
Labels
Override the default "Yes"/"No" text:
json
{
"id": "privacy_blocked",
"label": "Privacy Blocked",
"type": "Boolean",
"value": "false",
"true_label": "Blocked",
"false_label": "Not blocked",
"true_color": "red"
}| Property | Default | Description |
|---|---|---|
true_label | "Yes" | Text shown when the value is true |
false_label | "No" | Text shown when the value is false |
Colors
Control the color of the true and false states independently:
json
{
"id": "shipped",
"label": "Shipped",
"type": "Boolean",
"value": "true",
"true_color": "green",
"false_color": "red"
}| Property | Default | Description |
|---|---|---|
true_color | field color | Color name shown when the value is true |
false_color | field color | Color name shown when the value is false |
If omitted, the normal field value color is used for both states. See Colors below for available color names.
Option
Fixed list of choices. The user cycles or selects from a dropdown.
Simple format (value equals label)
json
{
"id": "type",
"label": "Type",
"type": "Option",
"value": "Item",
"options": [
"",
"Item",
"Resource",
"G/L Account",
"Text"
]
}Labeled format (separate value and display label)
json
{
"id": "blocked",
"label": "Blocked",
"type": "Option",
"value": "",
"options": [
{
"value": "",
"label": " "
},
{
"value": "ship",
"label": "Ship"
},
{
"value": "invoice",
"label": "Invoice"
},
{
"value": "all",
"label": "All"
}
]
}Which format to use: use simple strings when the stored value and the display text are identical (e.g., "Item", "Resource"). Use labeled objects when they differ — for example, when a blank value should display as a space rather than an empty string, or when the code differs from the label.
Both formats are valid. The client handles either.
The client renders the current value with a ↓ indicator and supports:
- Space to cycle
Ctrl+Enterto open a selection modal- Backspace/Delete to reset to the first option
Password
Masked text input. Renders as ****.
json
{
"id": "password",
"label": "Password",
"type": "Password",
"value": ""
}Used for login forms.
Separator
Visual divider between field groups. Not interactive, not editable. The client skips separators entirely — they are not navigable, not included in changesets, and not referenced for autofill or validation.
Always use "separator" as the id:
json
{
"id": "separator",
"label": "",
"type": "Separator",
"value": ""
}Multiple separators on the same form all use the same id. The client ignores it.
DateRange
Range format for filter forms: 01-01-26..31-01-26.
json
{
"id": "date_filter",
"label": "Date Filter",
"type": "DateRange",
"value": ""
}TextArea
Multi-line text input for notes, comments, and message bodies.
json
{
"id": "notes",
"label": "Notes",
"type": "TextArea",
"value": "First line\nSecond line",
"rows": 4
}rowscontrols the visible height of the field (default: 4). The field can hold more text than the visible rows — the user scrolls within the field.- The value uses
\nas the line separator. Your server receives the value with\nembedded. - Works in Card and action form modals.
Navigation
TextArea uses a flat cursor model — the cursor is a position within the full string, and \n counts as one character.
| Key | Behavior |
|---|---|
Enter | Confirm edit, advance to next quick_entry field |
Ctrl+Enter | Insert a newline at the cursor |
F2 | Cycle: Cursor End → Cursor Start (Select All is skipped) |
Ctrl+A | Select all text |
Tab / Shift+Tab | Confirm edit, move to next/previous field |
Esc | Revert to original value, return to select mode |
The bottom bar shows the current line count while editing — for example 2/4 Ctrl+Enter New line.
Field values
All field value properties are strings, never null. An empty field is "". The client sends string values on save, and your server sends string values in responses. This applies to every field type including Boolean ("true" / "false") and Decimal ("1,495.00").
Color and bold
Use color and bold to override the default appearance of any field:
json
{
"color": "yellow",
"bold": true
}Both are optional. bold defaults to false and can be omitted. Used primarily on drill-down fields. See Colors below for available color names.
Validation rules
Add a validation object to enforce client-side rules:
json
{
"validation": {
"required": true,
"max_length": 100,
"min_length": 1,
"pattern": "^[A-Z0-9]+$",
"input_mask": "uppercase",
"min": 0,
"max": 999999.99,
"decimals": 2
}
}| Rule | Applies to | Behavior |
|---|---|---|
required | All types | Empty value rejected: "{Label} is required." |
max_length | Text types | Value longer than N characters rejected |
min_length | Text types | Value shorter than N characters rejected |
pattern | Text types | Regex — value not matching is rejected |
input_mask | Text types | "uppercase", "lowercase", "digits_only" — filters keystrokes |
min / max | Decimal, Integer | Out-of-range value rejected |
decimals | Decimal | Maximum decimal places |
These are client-side hints. Your server must still validate on save.
Colors
The following named colors are available wherever a color name is accepted — in color, true_color, and false_color:
| Name | Notes |
|---|---|
"yellow" | |
"red" | |
"green" | |
"blue" | |
"cyan" | |
"magenta" | |
"white" | |
"black" | |
"gray" / "grey" |
Color names are case-insensitive. An unrecognised name falls back to white.