Skip to content

Editor fields & datasets

<EditorFields> holds the create/edit form fields for a view. Each child is named after its field type. This page covers the field types and their attributes, plus the <Select> dataset system. The smart Required/Disabled/Hidden/Allow/Deny attributes and ValueExpression are introduced here but documented in full on Column & field expressions.

Name (required), Label, Required, Disabled, Hidden, Allow, Deny, Placeholder, DefaultValue, Width (1–12), and ValueExpression.

Required / Disabled / Hidden are “smart” attributes — each holds either a literal ("true"/"false") or a row-context expression. Allow / Deny are field-level security (whitelist / blacklist who may edit a field), server-enforced on submit. ValueExpression computes the field’s value. All of these are covered in detail under Column & field expressions.

<Events>
<On Type="Change"> <!-- Checked | Change | EnterPressed | Blur | RowEntered -->
<Script>field.value = (field.value || '').trim();</Script>
</On>
</Events>
Element Type-specific attributes
<Text> TextType (SingleLine|MultiLine|RichText|Email), MaxLength, Mask, AutoComplete, AutoCompleteSource
<Number> MinValue, MaxValue, DecimalPlaces, Step, ShowSpinButtons
<Boolean> DisplayType (Checkbox|Switch|RadioButtons), TrueLabel, FalseLabel
<Select> Searchable, Multiple, AllowClear, MaxSelection, ControlType (Select2|ModalSelector), EmptyOptionText + a <DataSet>, and optional <Columns> / <ExtraMappings> (see below)
<DateTime> / <Date> / <Time> Format, MinDate, MaxDate, ShowCalendar, AllowManualInput (the element name picks date/time/both)
<Attachment> Accept, MaxFiles, MaxSize (bytes), Multiple, UploadPath
<Password> MinLength, MaxLength, HashedParameterName
<Sequence> Format (required), Scope (required)
<CartTable> inline editable grid — see CartTable

A <Select> field draws its choices from a <DataSet>. The Type picks the source.

<Select Name="CustomerType"><DataSet Type="static">
<Option Value="Individual" Text="Individual" />
<Option Value="Business" Text="Business" />
</DataSet></Select>
Type Source
static (or options) inline <Option Value="" Text="" />
csv comma-separated values in the element body
sql a SELECT … AS Value, … AS Label query in the body (+ LoadOnStart)
model Schema="" Model=""reuses the static options of a <Select> field on that Genie entity: the target entity must declare a <Select> whose Name equals this editor field’s Name, and its <Option>s become the choices. For a lookup that lists another entity’s rows, use a sql dataset (SELECT Id AS Value, Name AS Label FROM …), not model.

A SQL dataset aliases the identifier as Value (submitted, hidden) and the display text as Label — or Text (the Select2 { id, text } convention is also accepted). If neither Label nor Text is present, the first column that isn’t Value is used as the label. Any other columns are “extras” — surfaced to the client for the modal table and <ExtraMappings>. The query self-filters using two server-injected parameters: @SearchText (%term% while typing, % when the box is opened with no filter) and @CurrentValue (the currently-selected value, for re-resolving its label). Session parameters (@SessionUserId, @SessionCompanyId, …) are injected too. View mode, and every field render before the dropdown is opened, resolves the stored value to its label through the same query — multi-selects resolve each comma-joined value.

<DataSet Type="sql">
SELECT Id AS Value, Name AS Label, Email, Phone
FROM Sales.Customers
WHERE IsDeleted = 0
AND (@SearchText = '%' OR Name LIKE @SearchText OR Email LIKE @SearchText
OR CAST(Id AS NVARCHAR(20)) = @CurrentValue)
</DataSet>

Every <Select> renders as a styled, always-searchable dropdown — there is no raw native <select>. ControlType="Select2" (default) and Searchable="true" are accepted for back-compat but no longer change anything: a dropdown is searchable regardless, and a dataset-backed one searches server-side (LIKE via @SearchText) while a static-option one filters client-side. ControlType="ModalSelector" instead opens a picker dialog showing the dataset rows in a table with a tick column on the left and a debounced search box at the top. Set Multiple="true" on any of them to select more than one value — stored comma-joined, capped by MaxSelection, and shown in the control as non-colored tag pills (remove a value by reopening the dropdown and unticking it). AllowClear (default true) adds a clear (×) button to a single-select; EmptyOptionText/Placeholder set the empty-state text.

Optional. Chooses, labels, and orders the columns shown in the ModalSelector table. Omit it and the table shows every dataset column except Value.

<Columns>
<Column Name="Label" Label="Customer" Width="40" /> <!-- Name = dataset column; Label/Width optional -->
<Column Name="Email" Width="35" />
<Column Name="Phone" />
</Columns>

Optional. When a row is picked, copies columns from that row into other form fields — e.g. choose a customer and auto-populate read-only email/phone fields. (For a multi-select, the most-recently ticked row is applied.)

<ExtraMappings>
<Map Column="Email" Field="CustomerEmail" /> <!-- row column -> target field name -->
<Map Column="Phone" Field="CustomerPhone" />
</ExtraMappings>

Worked example: sample/Inventory/models/views/Products.view.xml demonstrates every field type, including a model dataset (reusing the Product.Status enum), a sql lookup (Category), a ModalSelector with <Columns> + <ExtraMappings> (Supplier → autofill email), a multi-select, and RichText.