Fields
Every field has a type: what kind of value it holds. A field node can pick a widget: how that value is shown. Leave the widget out and the type's own is used.
| Type | Holds | Widgets | Options of its own |
|---|---|---|---|
char | One line of text | email, phone, url, password | size, pattern |
text | Several lines of text | — | size |
html | Formatted text, cleaned of scripts on every change | — | — |
integer | A whole number | rating (stars), scale (1 to 10 buttons) | min, max |
float | A decimal number | — | min, max, digits |
monetary | An amount of money | — | currencyField or currency, min, max, digits |
boolean | Yes or no | toggle | — |
date | A date | — | — |
datetime | A date and a time | — | — |
selection | One choice from a list, or several with multiple | radio, checkboxes | options, multiple |
many2one | A link to one record of another model, found by typing | — | relation, filter |
many2many | Links to several records | tags, checkboxes | relation, filter |
one2many | A table of lines that belong to this record | — | relation, fields, columns on the node |
reference | A link to a record of one of several models | — | models |
binary | A file, uploaded or dropped | — | accept, maxSize |
image | An image, with a preview | — | maxSize |
json | Structured data, checked as it is typed | — | — |
properties | Extra values shown read-only | — | — |
Every type also takes label, help, required, readonly and default.
Links to other records
many2one, many2many and reference find records through your data source's search. A filter limits what can be picked, and valueFrom follows another field — here, the regions of the chosen country:
"state_id": {
"type": "many2one",
"label": "Region",
"relation": "country.region",
"filter": [{ "field": "country_id", "op": "=", "valueFrom": "country_id" }]
}
Tables of lines
A one2many declares the fields of each line; the node's columns says which show as columns. Lines are added, edited and removed in place, and saved as create, update and delete operations — see what a save sends.
"child_ids": {
"type": "one2many",
"label": "Contacts",
"relation": "partner",
"fields": {
"name": { "type": "char", "label": "Name", "required": true },
"email": { "type": "char", "label": "Email" }
}
}
Your own widget
A widget is a function that gets the field and returns an element, an update that receives the current value, and a focus. Register it under a type, or under type.widget to offer it as a choice:
import type { WidgetFactory } from '@fieldia/widgets';
const colour: WidgetFactory = ({ form, name, id, document }) => {
const input = document.createElement('input');
input.type = 'color';
input.id = id;
input.addEventListener('input', () => form.setValue(name, input.value));
return {
element: input,
focus: () => input.focus(),
update: ({ value, readonly }) => {
input.value = String(value ?? '#000000');
input.disabled = readonly;
},
};
};
mountViewer(host, { page, dataSource, widgets: { 'char.colour': colour } });
// a node with "widget": "colour" on a char field now uses it
In React, Vue and Angular a custom field can be a component of that framework instead — pass it as fieldTypes.