Ga naar hoofdinhoud

CnObjectDataWidget

Schema-driven editable data grid widget. Displays object properties in a CSS grid, supports inline editing (click-to-edit with all widget types), dirty tracking, and saves via objectStore.

Usage

<CnObjectDataWidget
title="Character info"
:schema="schema"
:object-data="character"
object-type="characters" />

Props

PropTypeDefaultDescription
titleString'Data'Widget title in the card header
iconObject|FunctionnullOptional MDI icon component for the header
object-dataObjectrequiredThe object to display and edit. Keys must match the schema property keys.
schemaObjectrequiredJSON Schema defining properties. Must have a properties field.
object-typeString''Registered object type slug in the objectStore. Required for saving via objectStore.saveObject().
storeObjectnullOptional objectStore instance. When provided, used directly for saving instead of auto-detecting via Pinia.
overridesObject{}Per-property configuration overrides (see below)
columnsNumber3Number of grid columns
editableBooleantrueWhether editing is enabled globally — gates both inline (click-to-edit) and the full-form Edit action item
edit-labelString'Edit'Label for the Edit action item, which opens a schema-driven CnFormDialog pre-filled with the object (alongside inline editing)
excludeArray[]Property keys to hide from display
includeArraynullProperty keys to show (whitelist — all others hidden)
save-labelString'Save'Label for the save button
discard-labelString'Discard'Label for the discard button
empty-labelString'No data available'Label when no properties are found
documentation-urlString''Documentation link surfaced in the widget's overflow Actions menu (empty hides the Documentation item).
widget-idString''Stable id forwarded to the widget chrome (falls back to object-type).
metadata-labelString'Metadata'Label for the Metadata item in the overflow Actions menu.

Slots

SlotScoped propsDescription
#actionsExtra buttons in the widget header (right side, next to save/discard)
#field-{key}{ field, value, update, cancel }Override the inline editor for a specific property
#display-{key}{ field, value, raw }Override the display (read-only) view for a specific property

Events

EventPayloadDescription
@savedresult objectEmitted after a successful objectStore save
@save-errorerror messageEmitted when the objectStore save fails
@savemerged data objectEmitted when no objectType is set — lets the parent handle the save
@discardEmitted when the user clicks the discard button

One config, two surfaces (display + edit modal)

The overrides / exclude / include props drive a single fieldsFromSchema pipeline that both the inline display and the full-form Edit modal (CnFormDialog) consume. So a property hidden via overrides.id.hidden = true is hidden in the widget grid and dropped from the edit form; an order set on a property reorders both. gridColumn/gridRow (span) are display-only; the modal is single-column (stacked).

fieldsFromSchema honors, per property: hidden (drop the field), order (wins over the schema's own order for sorting), readOnly: false (un-skip a schema-readonly field), plus any field props to merge (label, widget, enum, …).

Configuring it in-app

On a detail page in OpenBuild edit mode, the widget's cog opens CnObjectDataWidgetForm: it lists the schema's properties (resolved from the widget's register/schema, or the page's injected cnObjectContext when the widget inherits them) and lets you, per property, toggle visibility, set a label, span, editor type and editable, drag to reorder, and pick a layout preset (Stacked / 2-col / 3-col → the columns value). The form emits a minimal overrides map persisted on the widget's content.overrides.

Property overrides

The overrides prop accepts per-property configuration:

{
propertyKey: {
order: 1, // Sort order (lower = first)
gridColumn: 2, // Number of grid columns to span
gridRow: 2, // Number of grid rows to span
hidden: false, // Whether to hide this property
editable: true, // Whether this property can be edited
label: 'Custom', // Override the display label
widget: 'textarea', // Override the widget type for editing
enum: [...], // Override enum values for select/multiselect
}
}

Supported widget types

The widget auto-detects the editor based on the JSON Schema property type:

WidgetSchema typeEditor
textstringText input
emailstring format emailEmail input
urlstring format uriURL input
numbernumber/integerNumber input
textareastring (long)Textarea
selectstring with enumSingle select dropdown
multiselectarray with enumMulti-select dropdown
tagsarray (no enum)Tag input
checkboxbooleanToggle switch
datestring format dateDate picker
datetimestring format date-timeDatetime picker

Example with overrides

<CnObjectDataWidget
title="Publication details"
:schema="publicationSchema"
:object-data="publication"
object-type="publications"
:overrides="{
title: { order: 1, gridColumn: 2 },
description: { order: 2, gridColumn: 2, widget: 'textarea' },
status: { order: 3, editable: false },
internalNotes: { hidden: true },
}" />

Conditional immutability (x-openregister-readonly-when)

A schema property can declare that it becomes read-only when another field on the same object holds a given value — the widget evaluates the rule against the live object data and renders the field locked (shown, not hidden). This is the declarative way to express identity fields that must not be edited in a particular state (e.g. a hybrid app's slug/name/description/ productionVersion, which mirror the installed app it customizes).

// In the OpenRegister schema property:
"slug": {
"type": "string",
"x-openregister-readonly-when": { "field": "appType", "equals": "hybrid" }
}
// or match a set of values:
"slug": { "type": "string", "x-openregister-readonly-when": { "field": "appType", "in": ["hybrid", "managed"] } }

An unconditional "readOnly": true on the property locks the field in every state (still shown, never editable). Both are honoured by isEditable; a per-field overrides[key].editable still takes priority. Read-only here is a UI affordance — pair it with server-side enforcement (an OpenRegister write guard / listener) for the authoritative boundary.