Skip to content

Widgets

Widgets control how fields are displayed and edited.

When no explicit widget is specified in a view, the system automatically selects a default widget based on the field type:

Field TypeDefault Widget
CharTextInput
TextTextArea
IntegerNumberInput
FloatNumberInput
MonetaryMonetary
BooleanCheckbox
DateDatePickerInput
DatetimeDateTimePicker
SelectionSelectCombo
ManyToOneDataCombo
OneToOneDataCombo
ManyToManyMultiCombo
OneToManyList
FileFileUpload
JSONJSONInput

You can override the default by specifying a widget property:

{
"type": "field",
"name": "status",
"properties": {
"widget": "Badge"
}
}

Widgets support different view modes (Form, List, FormList, Kanban, Display). When a widget is used in an unsupported mode, it falls back to display mode if available, or shows “Unsupported widget”.

WidgetFormListFormListKanbanDisplayNotes
Dashboard Widgets
Card---KPI/metric display
CompactList--Summary table/list
Display Widgets
LinkedRecords---Related records with actions
Avatar
Badge
BarChart--Not suitable for inline table cells
AreaChart--Not suitable for inline table cells
SparklineCompact, suitable for inline
Image
ProgressBar
Rating
StatusBar----Top-level form element type: statusbar, not a field widget
Input Widgets
TextInput
TextArea
NumberInput
Monetary
Checkbox
Switch
DatePickerInput
DateTimePicker
DateRangePicker---Form + Display only
TimeInput
ColorInput
RangeSlider--Not suitable for inline editing
Slider--Not suitable for inline editing
RichTextEditor---Form + Display only
FileInput
RadioCards
PasswordInput----Form-only by design
JSONInput
FormulaInputSandboxed formula editor with ƒx palette
MultiFileUploadMultiple file attachments
CodeEditorSyntax-highlighted code (CodeMirror)
SignatureCanvas signature; stored as PNG data URL
Select Widgets
SelectCombo
Radio
DataCombo
AvatarComboDataCombo with avatar display
MultiCombo
GroupAccessManager--Complex UI, form-only editing
MultiOptionGroup--Complex UI, form-only editing
Stepflow---Breadcrumb stepper for Selection state (form + display)
Layout Widgets
List---Embedded editable list (FormList)
Tags-
TitleSection headers
Divider---Visual separator
Button---Action button
LinkButtonNavigation button
Additional Input Widgets
PinInput----Form-only, numeric PIN entry
SegmentedControlButton group selection
MonthPickerInputMonth selector
YearPickerInputYear selector
ObjectFieldsInput---JSON object editor
FilterBuilder---Query filter builder
Additional Display Widgets
Icon--Lucide icon display
BoxedIcon---Icon with background
WebsitePreview--Website iframe preview

Legend:

  • ✓ = Supported
  • - = Not supported (falls back to display mode or shows “Unsupported widget”)

Single-line text input.

{
"type": "field",
"name": "name",
"properties": {
"widget": "TextInput",
"placeholder": "Enter name",
"size": "lg"
}
}
PropertyDescription
placeholderPlaceholder text
sizexs, sm, md, lg, xl
disabledDisable input

Multi-line text input.

{
"type": "field",
"name": "description",
"properties": {
"widget": "TextArea",
"rows": 4,
"placeholder": "Enter description"
}
}

WYSIWYG HTML editor.

{
"type": "field",
"name": "content",
"properties": {
"widget": "RichTextEditor"
}
}

Syntax-highlighted code editor (CodeMirror 6) for script/markup fields. Select the language with the language prop — not mode (mode is the view render mode).

{
"type": "field",
"name": "custom_js",
"properties": {
"widget": "CodeEditor",
"language": "javascript"
}
}
PropertyDescription
languagejson, javascript, python, markdown, or html (defaults to plain)
minHeightEditor min height (e.g. "160px")

Canvas-based signature capture (no external dependency). The drawn signature is stored on the field as a PNG data URL string; read-only and display modes render it as an image. Back it with a Text/Char field.

{
"type": "field",
"name": "signature",
"properties": {
"widget": "Signature",
"label": "Customer Signature"
}
}

Numeric input with optional formatting.

{
"type": "field",
"name": "price",
"properties": {
"widget": "NumberInput",
"precision": 2,
"prefix": "$",
"min": 0
}
}
PropertyDescription
precisionDecimal places
prefixStatic text before value (e.g., "$", "€")
suffixStatic text after value (e.g., "%", "kg")
minMinimum value
maxMaximum value

:::tip Dynamic Prefix/Suffix For dynamic values from related fields (e.g., displaying UOM name), define prefix_field or suffix_field on the model field definition instead:

# Model definition
quantity = Float(precision=3, suffix_field="uom__name")

The model’s dynamic fields take priority over the view’s static values. See Prefix and Suffix Fields. :::

The money widget — the default for Monetary fields and the right choice whenever a value is currency. It formats the amount with the record’s currency symbol, position and rounding, and is locale-aware. Bind the currency with currency_field (the model field holding the currency object); in dashboard/display widgets the alias currencyField is also accepted.

- type: field
name: amount
properties:
widget: Monetary
currency_field: currency
PropertyDescription
currency_fieldSibling field holding the currency (symbol/position/rounding). Prefer setting currency_field on the model field so it applies everywhere.
precisionOverride decimal places (otherwise from the currency’s rounding)

:::tip Model-side currency For form fields bound to a model column, set currency_field on the field definition itself rather than repeating it in every view. See Prefix and Suffix Fields. :::

Raw JSON editor — the default widget for JSON fields. It pretty-prints the value, validates on blur, and saves the parsed object (not the string). Display and kanban modes render the JSON read-only in a code block.

- type: field
name: procurement_trace
properties:
widget: JSONInput
readonly: true
visible: Q(procurement_trace__isnotnull=True)
PropertyDescription
minRowsMinimum textarea rows in form mode (default: 4)
maxRowsMaximum textarea rows before scrolling (default: 12)
placeholderPlaceholder text

For an object editor with typed key/value rows instead of raw text, see ObjectFieldsInput.

A single-line editor for safe-eval formula fields (e.g. salary components, financial report lines). It surfaces the expression vocabulary through a ƒx palette listing the available variables and functions, and validates client-side (no string literals, only known names) so mistakes surface before save.

The variable namespace comes from one of two sources:

# Server namespace: a no-arg classmethod returning {variables, functions}
- type: field
name: formula
properties:
widget: FormulaInput
label: Formula
namespaceModel: Payslip
namespaceMethod: formula_namespace
# Sibling-row namespace: variables are the live values of a peer grid column
- type: field
name: formula
properties:
widget: FormulaInput
label: Formula
placeholder: e.g. revenue - cogs
variablesFromField: code # peer column supplying variable names
variableLabelField: label # peer column used as each variable's description
PropertyDescription
namespaceModelModel whose formula_namespace() supplies variables/functions (default Payslip)
namespaceMethodClassmethod name returning {variables, functions} (default formula_namespace)
variablesFromFieldSource variables from a sibling grid column instead of the server
variableLabelFieldSibling column used as each variable’s description
placeholderPlaceholder formula

Upload and manage multiple file attachments on one field. Form mode shows the uploader; list/kanban show a count badge; display shows the file-name badges.

- type: field
name: attachments
properties:
widget: MultiFileUpload
label: Attachments
PropertyDescription
acceptAccepted MIME types / extensions (e.g. "image/*,.pdf")

For a single file, use FileInput/ImageInput.

Date selector.

{
"type": "field",
"name": "due_date",
"properties": {
"widget": "DatePickerInput"
}
}

Date and time selector.

{
"type": "field",
"name": "scheduled_at",
"properties": {
"widget": "DateTimePicker"
}
}

Boolean toggle.

{
"type": "field",
"name": "active",
"properties": {
"widget": "Switch",
"label": "Active"
}
}

Boolean checkbox.

{
"type": "field",
"name": "terms_accepted",
"properties": {
"widget": "Checkbox",
"label": "I accept the terms"
}
}

Radio button group for Selection fields and ManyToOne fields.

Selection field example:

{
"type": "field",
"name": "priority",
"properties": {
"widget": "Radio",
"orientation": "horizontal"
}
}

ManyToOne field example:

{
"type": "field",
"name": "category",
"properties": {
"widget": "Radio",
"orientation": "vertical",
"filter": "Q(active__eq=true)"
}
}
PropertyDescription
orientationhorizontal (default) or vertical
sizexs (default), sm, md, lg
filterQ-expression to filter M2O options
colorMantine color for radio buttons

For ManyToOne fields, all records from the related model are fetched and displayed as radio options.

Card-based radio selection with icon, label, and description. Supports both Selection fields and ManyToOne fields. Ideal for visually rich option selection.

Selection field with custom options:

{
"type": "field",
"name": "type",
"properties": {
"widget": "RadioCards",
"columns": 3,
"options": [
{
"value": "Consumable",
"label": "Consumable",
"icon": "Package",
"description": "Used once, not tracked in inventory"
},
{
"value": "Stockable",
"label": "Stockable",
"icon": "Warehouse",
"description": "Tracked in inventory with stock levels"
},
{
"value": "Service",
"label": "Service",
"icon": "Wrench",
"description": "Non-physical service offering"
}
]
}
}

ManyToOne field example:

{
"type": "field",
"name": "product_category",
"properties": {
"widget": "RadioCards",
"icon": "Folder",
"columns": 2,
"filter": "Q(parent__isnull=true)"
}
}
PropertyDescription
optionsArray of option objects with value, label, icon, description
columnsNumber of columns for grid layout
sizesm, md (default), lg
iconFallback icon for all cards (required for M2O, optional for Selection)
filterQ-expression to filter M2O options
colorMantine color for badges in display modes

Option object properties (for Selection fields):

PropertyRequiredDescription
valueYesThe value stored when selected
labelNoDisplay label (defaults to value)
iconNoLucide icon name (overrides fallback icon prop)
descriptionNoDescription text below label

Notes:

  • For Selection fields: options can be provided explicitly or derived from the field’s choices
  • For ManyToOne fields: all records are fetched from the related model. Use icon prop to set a fallback icon (defaults to IconCircle if not provided)
  • Both widgets support groups, visible, and readonly properties (handled at the form level)

Selection dropdown for Selection fields.

{
"type": "field",
"name": "status",
"properties": {
"widget": "SelectCombo"
}
}

Dropdown for ManyToOne fields.

{
"type": "field",
"name": "customer",
"properties": {
"widget": "DataCombo",
"filter": "Q(is_customer=True)"
}
}
PropertyDescription
filterDomain filter for options
createAllow creating new records
contextDefault values for “Create & Edit” (see Field-Level Context)

Filters can reference current form/row values using three patterns:

PatternDescriptionExample
[field]Bracketed field referenceQ(company__in=[company])
[field__nested]Bracketed nested traversalQ(currency__eq=[contact__company])
_parent.fieldParent form field (in line items)Q(company__in=[_parent.company])
_parent.field__nestedParent’s nested fieldQ(currency__eq=[_parent.contact__company])
field__nestedUnbracketed (after =)Q(currency__eq=contact__company)

:::warning Depth Limitation Right-side field references are limited to 2 levels of relation traversal due to backend serialization depth. The install/update process validates this and raises an error if exceeded.

DepthExampleValid
1contact__id
2contact__company__id
3contact__company__currency__id✗ Error

Workarounds for deep nesting:

  1. Add a related_field on the model to surface the value at a shallower level
  2. Let the backend handle the filter (don’t use field references) :::

Example - Filter by parent form’s company (in invoice line items):

{
"type": "field",
"name": "account",
"properties": {
"widget": "DataCombo",
"filter": "Q(type__nin=['Receivable','Payable']) & (Q(companies__in=[_parent.company]) | Q(companies__isnull=True))"
}
}

Example - Unbracketed field reference:

{
"type": "field",
"name": "currency",
"properties": {
"widget": "DataCombo",
"filter": "Q(id__eq=contact__company__currency)"
}
}

Dropdown for ManyToOne fields with avatar display. Similar to DataCombo but shows avatars alongside names in the dropdown options and selected value. Ideal for user/contact selection fields.

{
"type": "field",
"name": "assigned_to",
"properties": {
"widget": "AvatarCombo",
"avatarField": "avatar",
"filter": "Q(active=True)"
}
}
PropertyTypeDefaultDescription
avatarFieldString"avatar"Field name on related model containing avatar attachment ID
avatarSizeString"sm"Avatar size (xs, sm, md, lg, xl)
avatarRadiusString"xl"Avatar border radius
filterString-Domain filter for options (same as DataCombo)
createBooleanfalseAllow creating new records
contextObject-Default values for “Create & Edit”

Mode Behavior:

ModeBehavior
FormFull AvatarCombo input with edit/readonly support
ListAvatar combo in edit mode, avatar + name display in view mode
FormListSame as List
KanbanAvatar + name display only (no input)
DisplayAvatar + name with tooltip

Example - User assignment with avatar:

{
"type": "field",
"name": "user_id",
"properties": {
"widget": "AvatarCombo",
"avatarField": "avatar",
"avatarSize": "sm",
"filter": "Q(active=True) & Q(groups__name__in=['Sales'])"
}
}

Note: The avatarField should reference an attachment ID field (File type) on the related model. The widget fetches and caches avatar images automatically.

Multi-select for ManyToMany fields.

{
"type": "field",
"name": "tags",
"properties": {
"widget": "MultiCombo"
}
}
PropertyDescription
filterDomain filter for options
createAllow creating new records
contextDefault values for “Create & Edit” (see Field-Level Context)

Image upload field.

{
"type": "field",
"name": "photo",
"properties": {
"widget": "ImageInput"
}
}

Color picker.

{
"type": "field",
"name": "color",
"properties": {
"widget": "ColorInput"
}
}

Button group for mutually exclusive options. Works with Selection fields.

{
"type": "field",
"name": "view_mode",
"properties": {
"widget": "SegmentedControl",
"fullWidth": true
}
}
PropertyDescription
fullWidthExpand to fill container width
sizexs, sm, md, lg, xl
colorMantine color for active segment

Month and year selector.

{
"type": "field",
"name": "billing_month",
"properties": {
"widget": "MonthPickerInput"
}
}

Year selector.

{
"type": "field",
"name": "fiscal_year",
"properties": {
"widget": "YearPickerInput"
}
}

Numeric PIN entry with individual character boxes.

{
"type": "field",
"name": "verification_code",
"properties": {
"widget": "PinInput",
"length": 6
}
}
PropertyDescription
lengthNumber of input boxes (default: 4)
typenumber (default) or alphanumeric
maskHide input with asterisks

Plain text display.

{
"type": "field",
"name": "name",
"properties": {
"widget": "Text",
"fw": "600",
"size": "lg",
"c": "dimmed"
}
}
PropertyDescription
fwFont weight (400-900)
sizexs, sm, md, lg, xl
cColor (dimmed, or hex)
lineClampMax lines to show
htmlRender the value as raw HTML instead of plain text (e.g. a formatted address)

Rendering raw HTML: set html: true to inject the field value as HTML — useful for server-formatted blocks such as a multi-line address.

- type: field
name: contact_address
properties:
widget: Text
nolabel: true
html: true
c: dimmed
size: sm

There is no separate Html widget — raw-HTML display is the html prop on Text. The HTML must come from trusted server-side rendering.

Colored badge.

{
"type": "field",
"name": "status",
"properties": {
"widget": "Badge",
"variant": "dot",
"size": "sm",
"colors": {
"draft": "gray",
"active": "green",
"archived": "red"
}
}
}
PropertyDescription
variantfilled, outline, dot
sizeBadge size
colorsColor mapping by value

Display multiple tags.

{
"type": "field",
"name": "tags",
"properties": {
"widget": "Tags",
"size": "sm"
}
}

Display-only avatar widget with automatic image fetching. Shows user initials when no image is available.

{
"type": "field",
"name": "user_id",
"properties": {
"widget": "Avatar",
"avatarField": "avatar",
"size": "md"
}
}
PropertyTypeDefaultDescription
avatarFieldString"avatar"Field name on value object containing attachment ID
sizeString"md"Avatar size (xs, sm, md, lg, xl)
radiusString"xl"Border radius
colorString"initials"Background color for initials

How it works:

The widget automatically fetches avatar images when:

  • Value is an object with an attachment ID field (specified by avatarField)
  • Value itself is an attachment ID (number)
  • Fallback fields: image, avatar on the value object

Example - Display user avatar in a list:

{
"type": "field",
"name": "assigned_to",
"properties": {
"widget": "Avatar",
"avatarField": "avatar",
"size": "sm"
}
}

Display image.

{
"type": "field",
"name": "image",
"properties": {
"widget": "Image",
"h": 100,
"w": 100,
"fit": "cover"
}
}
PropertyDescription
hHeight in pixels
wWidth in pixels
fitcover, contain, fill

Star rating display.

{
"type": "field",
"name": "rating",
"properties": {
"widget": "Rating",
"count": 5
}
}

Display a Lucide icon.

{
"type": "field",
"name": "icon_name",
"properties": {
"widget": "Icon",
"size": 24,
"color": "blue"
}
}
PropertyDescription
sizeIcon size in pixels
colorMantine color (e.g., blue, red.6)

Icon with colored background box.

{
"type": "field",
"name": "icon_name",
"properties": {
"widget": "BoxedIcon",
"size": 40,
"color": "teal"
}
}
PropertyDescription
sizeBox size in pixels
colorMantine color for background

Progress bar display.

{
"type": "field",
"name": "completion",
"properties": {
"widget": "ProgressBar",
"color": "blue",
"size": "md"
}
}
PropertyDescription
colorMantine color
sizexs, sm, md, lg, xl
stripedShow striped pattern
animatedAnimate the stripes

A breadcrumb-style stepper for a Selection state field — renders the choices as Draft › Sent › Order › Done with the current value highlighted as a pill. It is a top-level form element (type: stepflow, bound by name) placed near the status ribbon, not buried in the grid. Read-only by default.

- type: stepflow
name: state
properties:
hideInactive:
- Cancelled
PropertyDescription
hideInactiveList of state values to hide unless they are the current value (e.g. terminal states like Cancelled)

The steps are derived automatically from the bound Selection field’s choices, so they are the human-readable state labels — no step list is configured in the view. Supported in Form and Display modes only.

Dashboard widgets display KPIs, metrics, and summary data in form views. They support locale-aware number formatting using the user’s language settings.

:::info Display Widget Properties Dashboard and display widgets (Card, CompactList, Charts) can specify currencyField directly in view properties because they display arbitrary data rather than mapping to model fields. For form fields bound to model definitions, use currency_field on the model instead. The prefix and suffix properties are always static strings. :::

Displays a KPI/metric card with value, label, icon, and optional click action. Perfect for dashboard overviews.

{
"type": "field",
"name": "total_revenue",
"properties": {
"widget": "Card",
"label": "Total Revenue",
"icon": "DollarSign",
"color": "green",
"format": "currency",
"currencyField": "currency",
"method": "action_view_revenue_details"
}
}
PropertyTypeDefaultDescription
labelString"Value"Display label above the value
iconString"ChartBar"Lucide icon name
colorString"blue"Mantine color for icon/hover
formatString-Format type: currency, number, integer, percent
currencyFieldString-Field path containing currency object (e.g., "currency", "company__currency")
prefixString-Static prefix text (e.g., "$", "€")
suffixString-Static suffix text (e.g., "%", "kg")
precisionNumber/String2Decimal places (static int) or field path (e.g., "uom__rounding")
methodString-Action method to call when clicked

A compact table/list for displaying summary data like top customers, recent items, etc.

Model field:

top_customers = JSON(description="Top Customers", default=[])

View usage:

{
"type": "field",
"name": "top_customers",
"properties": {
"widget": "CompactList",
"currencyField": "currency",
"columns": [
{ "field": "name", "label": "Customer", "flex": 2, "bold": true },
{ "field": "count", "label": "Orders", "align": "center", "format": "integer" },
{ "field": "amount", "label": "Total", "format": "currency", "color": "blue", "bold": true }
],
"method": "action_view_customer"
}
}

CompactList Properties:

PropertyTypeDefaultDescription
columnsArrayAuto-generatedColumn definitions (see below)
currencyFieldString-Field path containing currency object (e.g., "currency")
prefixString-Static prefix text (e.g., "$", "€")
suffixString-Static suffix text (e.g., "%", "kg")
showHeaderBooleantrueShow column headers
emptyTextString"No data available"Text when list is empty
methodString-Action method called on row click (receives item_id, item)

Column Properties:

PropertyTypeDefaultDescription
fieldStringRequiredKey in the data object
labelStringField nameColumn header label
formatString"text"text, currency, number, integer, percent, badge
precisionNumber/String2Decimal places (static int) or field path
alignStringAutoleft, center, right (numbers default to right)
flexNumber1Flex grow value
widthString-Fixed column width
colorString-Mantine color for text
boldBooleanfalseBold text
badgeColorString"gray"Badge color when format is badge

Displays related records from a JSON field as cards with customizable layout and row actions. Useful for showing credit notes, related documents, or any list of linked items with action buttons.

Model field:

outstanding_credits = JSON(description="Outstanding Credits", default=[])

View usage:

{
"type": "field",
"name": "outstanding_credits",
"properties": {
"widget": "LinkedRecords",
"title": "Available Credits",
"content": [
{
"type": "row",
"content": [
{ "type": "field", "name": "record_type", "properties": { "widget": "Badge", "color": "blue" } },
{ "type": "field", "name": "number", "properties": { "fw": 600 } }
]
},
{
"type": "row",
"content": [
{ "type": "field", "name": "date", "properties": { "widget": "Date", "c": "dimmed" } },
{ "type": "field", "name": "amount", "properties": { "widget": "Float", "currency": "currency" } }
]
}
],
"rowActions": [
{ "icon": "ExternalLink", "method": "action_view", "tooltip": "View" },
{ "icon": "Check", "method": "action_apply", "tooltip": "Apply", "confirm": "Apply this credit?" }
]
}
}

LinkedRecords Properties:

PropertyTypeDefaultDescription
titleString-Title displayed above the cards
contentArrayAuto-generatedLayout definition with rows and fields
rowActionsArray[]Action buttons for each card
emptyTextString"No records"Text when list is empty
hideWhenEmptyBooleantrueHide widget when no records
maxHeightNumber-Maximum height with scroll
visibleBoolean/String-Visibility (Q-expression supported)
readonlyBoolean/String-Hide actions when true
groupsArray-Group-based access control

Field Widgets in Content:

WidgetDescription
TextDefault text display
BadgeColored badge (color property)
DateFormatted date
FloatFormatted number with currency/prefix/suffix support

Float Field Properties:

PropertyDescription
currencyField name containing currency object (symbol, position, rounding)
prefixStatic string or field path (e.g., "uom__name")
suffixStatic string or field path
precisionNumber or field path for decimal places

Row Action Properties:

PropertyTypeDescription
iconStringLucide icon name
methodStringAction method to call (receives item_id, item)
tooltipStringHover tooltip
colorStringIcon color
confirmStringConfirmation message before action
visibleStringSimple Q-expression for conditional visibility

Chart widgets display visual data representations. They work with JSON fields containing numeric arrays or structured data. All chart widgets support currency formatting and locale-aware number display.

A compact inline chart perfect for showing trends in list views, kanban cards, and forms. Expects a JSON field with an array of numbers.

Model field:

sales_trend = JSON(description="Sales Trend", default=[])

View usage:

{
"type": "field",
"name": "sales_trend",
"properties": {
"widget": "Sparkline",
"w": 120,
"h": 24,
"color": "blue",
"curveType": "linear"
}
}
PropertyTypeDefaultDescription
wNumber100Width in pixels
hNumber30Height in pixels
colorString"blue"Mantine color (e.g., "teal", "red.6")
curveTypeString"linear"Curve type: linear, bump, natural, monotone, step
strokeWidthNumber2Line stroke width
fillOpacityNumber0.2Fill opacity (0-1)
withGradientBooleantrueUse gradient fill
trendColorsObject-Dynamic colors based on trend (see below)

Trend Colors:

Use trendColors instead of color to change the chart color based on trend direction:

{
"type": "field",
"name": "performance_data",
"properties": {
"widget": "Sparkline",
"trendColors": {
"positive": "teal",
"negative": "red",
"neutral": "gray"
}
}
}
  • positive: Color when first value < last value (upward trend)
  • negative: Color when first value > last value (downward trend)
  • neutral: Color when first value = last value

Bar chart for visualizing data with multiple series.

Model field:

monthly_data = JSON(description="Monthly Data", default=[])

Data format:

[
{"month": "Jan", "sales": 100, "costs": 60},
{"month": "Feb", "sales": 120, "costs": 70},
{"month": "Mar", "sales": 90, "costs": 55}
]

View usage:

{
"type": "field",
"name": "monthly_data",
"properties": {
"widget": "BarChart",
"dataKey": "month",
"h": 150,
"currencyField": "currency"
}
}
PropertyTypeDefaultDescription
dataKeyStringRequiredField name for X-axis labels
hNumber150Chart height in pixels
currencyFieldString-Field path containing currency object (e.g., "currency", "company__currency")
prefixString-Static prefix text (e.g., "$", "€")
suffixString-Static suffix text (e.g., "%", "kg")
precisionNumber/String2Decimal places (static int) or field path (e.g., "uom__rounding")

The chart automatically generates series from all numeric fields in the data (excluding the dataKey field).

Area chart with the same properties as BarChart.

{
"type": "field",
"name": "trend_data",
"properties": {
"widget": "AreaChart",
"dataKey": "date",
"h": 200,
"currencyField": "currency",
"precision": 0
}
}

Values in chart tooltips are formatted using the user’s locale settings (decimal and thousands separators from Language profile).

Embedded list view for OneToMany fields.

{
"type": "field",
"name": "order_lines",
"properties": {
"widget": "List",
"view": "order_line_list_view",
"create": true,
"delete": true,
"context": {
"form_identifier": "order_line_form_view",
"default_qty": 1
}
}
}
PropertyDescription
viewList view identifier to use
createAllow creating new records
deleteAllow deleting records
editabletrue for inline editing, "modal" for modal editing
limitMaximum rows to display initially (default: 100). Shows “Load more” button when exceeded
contextDefault values and view references (see Field-Level Context)

For large OneToMany lists, use the limit property to enable client-side pagination:

{
"type": "field",
"name": "order_lines",
"properties": {
"widget": "List",
"editable": true,
"limit": 50
}
}

When rows exceed the limit:

  • Only the first limit rows are displayed initially
  • A “Load X more (Y remaining)” button appears on the right
  • Clicking the button loads the next batch of rows
  • Pagination resets when navigating to a different record

List columns (fields in the List view) support visible, readonly, required, and filter properties with Q-expression evaluation. These are evaluated per-row against the row data.

{
"type": "field",
"name": "discount_amount",
"properties": {
"widget": "NumberInput",
"visible": "Q(has_discount__eq=true)",
"readonly": "Q(is_locked__eq=true)",
"required": "Q(amount__gt=0)"
}
}

Parent Data Access:

Use the _parent. prefix to access fields from the parent form (the form containing the List widget):

{
"type": "field",
"name": "account",
"properties": {
"widget": "DataCombo",
"filter": "Q(companies__in=[_parent.company]) | Q(companies__isnull=True)"
}
}

Nested Field Access:

Use __ for traversing relationships (Django ORM style):

{
"type": "field",
"name": "price",
"properties": {
"readonly": "Q(_parent.contact__company__locked__eq=true)"
}
}
PropertyTypeDescription
visibleBoolean/StringPer-row visibility. false hides cell, Q-expression evaluated per-row
readonlyBoolean/StringPer-row readonly. true or Q-expression
requiredBoolean/StringPer-row required. true or Q-expression
filterStringQ-expression filter for DataCombo/MultiCombo. Supports _parent. prefix

Embedded kanban view.

{
"type": "field",
"name": "tasks",
"properties": {
"widget": "Kanban",
"view": "task_kanban_view"
}
}
PropertyTypeDescription
labelstringField label
nolabelbooleanHide label
placeholderstringPlaceholder text
sizestringSize variant
visibleBoolean/StringShow/hide field. Can be false or Q-expression
readonlyBoolean/StringMake field read-only. Can be true or Q-expression
requiredBoolean/StringMake field required. Can be true or Q-expression
groupsArrayGroup identifiers for access control

Example with visibility/required:

{
"type": "field",
"name": "price",
"properties": {
"widget": "NumberInput",
"readonly": true,
"required": "Q(type__eq='product')"
}
}

See Element Properties for details.

PropertyTypeDescription
fwstring/numberFont weight
cstringText color
mtstringMargin top
mbstringMargin bottom
styleobjectCustom CSS

Field-level context allows you to pass default values and configuration to related record creation. This is useful for:

  • Pre-populating fields when creating records from embedded lists
  • Setting defaults when using “Create & Edit” in DataCombo/MultiCombo
  • Specifying which form view to use for modal editing

Use the context property with default_<fieldname> keys:

{
"type": "field",
"name": "order_lines",
"properties": {
"widget": "List",
"context": {
"default_qty": 1,
"default_uom": 5,
"form_identifier": "order_line_form_view"
}
}
}
Key PatternDescription
default_<field>Pre-populate field with value when creating new records
form_identifierForm view identifier for modal editing
Custom keysAvailable via self._ctx in backend methods

The full context object is passed to the backend and is accessible via self._ctx on model instances.

List widget with defaults:

{
"type": "field",
"name": "invoice_lines",
"properties": {
"widget": "List",
"editable": true,
"context": {
"default_quantity": 1,
"default_tax_included": true
}
}
}

DataCombo with Create & Edit defaults:

When users click “Create & Edit” in a DataCombo, the context values are passed to the new record form:

{
"type": "field",
"name": "contact",
"properties": {
"widget": "DataCombo",
"create": true,
"context": {
"default_is_customer": true,
"default_company": 5
}
}
}

Context is passed to the backend when creating new records. The backend processes default_* in _default_get and makes the full context available via self._ctx:

class OrderLine(Model):
async def _default_get(cls, context=None):
"""Called during record creation with field-level context."""
defaults = await super()._default_get(context)
# default_* keys are automatically applied by the base method
# Access custom context values for additional logic
if context and context.get('custom_flag'):
defaults['some_field'] = compute_default()
return defaults
async def compute_some_field(self):
"""Access context in computed fields or any method."""
# self._ctx contains the full context passed from frontend
if self._ctx.get('default_currency'):
# Use context value
pass