Zum Hauptinhalt springen

Forms

The form namespace provides a declarative UI toolkit for building structured data-entry forms inside ZeyOS weblets. Layout containers and input controls render natively in the ZeyOS interface — no HTML or CSS required. The form namespace only works in weblets; using it in services, resources, or standalone zeysdk run produces no visible output.

When a form is submitted, each control's id attribute becomes a key in the entity's extended data (EXTDATA). Use $EXTDATA.fieldId to read previously submitted values on subsequent loads.

In this chapter

  • hbox and vbox — horizontal and vertical layout containers
  • placeholder — empty spacer element
  • title, description, link, image, rule — display elements
  • textbox — text input with 17 type variants
  • checkbox — two-state toggle
  • listbox and listitem — single and multi-select lists
  • entitybox — ZeyOS entity record selector

Layout containers

hbox — Horizontal box

Arranges child form elements side by side in a row. The most common use is placing two or more fields on one line, or creating multi-column layouts with nested vbox containers. Accepts optional align, width, height, and padding attributes.

Full reference →

XML
<hbox>
<textbox id="firstname" label="First Name" width="300" />
<textbox id="lastname" label="Last Name" width="300" />
</hbox>

Multi-column layout with vbox nesting:

XML
<hbox>
<vbox width="50%">
<textbox id="company" label="Company" width="300" />
<textbox id="email" label="Email" type="email" width="300" />
</vbox>
<vbox width="50%">
<textbox id="phone" label="Phone" type="tel" width="300" />
<textbox id="website" label="Website" type="url" width="300" />
</vbox>
</hbox>

vbox — Vertical box

Stacks child form elements vertically. Use it inside an hbox to create columns, or standalone to control width and padding. Accepts optional align, width, height, and padding attributes.

Full reference →

XML
<hbox>
<vbox width="25%">
<title>Locations</title>
<foreach var="config.locations" var_value="location">
<checkbox id="loc_$location" caption="$location">$location</checkbox>
</foreach>
</vbox>
<vbox width="25%">
<title>Departments</title>
<foreach var="config.departments" var_value="dept">
<checkbox id="dept_$dept" caption="$dept">$dept</checkbox>
</foreach>
</vbox>
<vbox width="25%">
<textbox id="date_from" label="From" type="date" width="200" />
</vbox>
<vbox width="25%">
<textbox id="date_to" label="To" type="date" width="200" />
</vbox>
</hbox>

placeholder — Empty placeholder

Reserves empty space in a layout. Use it to balance columns when one side of an hbox has fewer controls, or to insert spacing between sections. Accepts optional width and height attributes.

Full reference →

XML
<hbox>
<textbox id="notes" type="multi" label="Additional Notes" />
<placeholder />
</hbox>

Display elements

title — Section title

Renders an emphasized heading that visually separates form sections.

Full reference →

XML
<title>Contact Information</title>
<hbox>
<textbox id="email" label="Email" type="email" width="300" />
<textbox id="phone" label="Phone" type="tel" width="300" />
</hbox>

<rule />

<title>Address</title>
<textbox id="street" label="Street" width="400" />
<hbox>
<textbox id="zip" label="ZIP" width="100" />
<textbox id="city" label="City" width="300" />
</hbox>

description — Labeled description

Displays read-only text attached to a label. Use it to show computed values, status information, or messages that the user cannot edit. Accepts an optional label attribute.

Full reference →

XML
<description label="Created">
<date:format format="d.m.Y">$EXTDATA.created</date:format>
</description>
<description label="Created by">$EXTDATA.creator_name</description>
<description label="Status">$EXTDATA.status</description>

Summary row with computed values:

XML
<hbox>
<description label="Total Net">$formatNum($totalNet)</description>
<description label="Total Gross">$formatNum($totalGross)</description>
<description label="Balance">$formatNum($balance)</description>
</hbox>

Renders a clickable hyperlink with a label. The content is the display text, and the url attribute sets the target.

Full reference →

XML
<link label="Customer Portal" url="./remotecall/portal/$ID">Open Portal</link>
<link label="Documentation" url="https://docs.example.com">View Docs</link>

image — Image

Renders an image with optional label, caption, and clickable url. The content provides the image source path or URL.

Full reference →


rule — Horizontal rule

Renders a horizontal divider line between form sections. Accepts an optional width attribute.

Full reference →

XML
<title>General</title>
<textbox id="name" label="Name" width="300" />

<rule />

<title>Details</title>
<textbox id="description" label="Description" type="multi" height="150" />

Input controls

textbox — Text input

The most versatile form control. Renders an editable input whose behavior changes based on the type attribute — from single-line text to a rich HTML editor, from a date picker to a currency input. Key attributes: id, label, type, width, placeholder, required, readonly, disabled, caption, pattern.

Full reference →

Input types

TypeDescriptionExtra attributes
singleSingle-line text inputcaption, pattern
multiMulti-line text areaheight
htmlRich HTML editorheight
emailEmail address input with validationcaption, pattern
urlURL input with validationcaption, pattern
telTelephone number inputcaption, pattern
passwordPassword input (masked characters)caption, pattern
numNumeric inputcaption
moneyMonetary value inputcaption
pricePrice input (general)caption
pricebillingPrice input (billing context)caption
priceprocurementPrice input (procurement context)caption
priceproductionPrice input (production context)caption
countryCountry code selector (ISO 3166-1 alpha-2)caption
currencyCurrency code selector (ISO 4217)caption
unitUnit code selector (UN/CEFACT Recommendation 20)caption
dateDate pickercaption
datetimeDate and time pickercaption

Example — Contact form with mixed types

XML
<title>Contact Details</title>
<hbox>
<vbox width="50%">
<textbox id="name" label="Full Name" width="300" required="true" />
<textbox id="email" label="Email" type="email" width="300" required="true" />
<textbox id="phone" label="Phone" type="tel" width="300" />
</vbox>
<vbox width="50%">
<textbox id="website" label="Website" type="url" width="300" />
<textbox id="country" label="Country" type="country" width="200" />
<textbox id="revenue" label="Annual Revenue" type="money" width="200" caption="" />
</vbox>
</hbox>

<rule />

<textbox id="notes" label="Notes" type="multi" height="200" />

Example — Date range filter

XML
<hbox>
<textbox id="date_from" label="From" type="date" width="200" />
<textbox id="date_to" label="To" type="date" width="200" />
</hbox>

Example — Numeric inputs with loop

XML
<for var="quarter" from="1" to="4">
<hbox>
<textbox id="revenue_q$quarter$" type="money" width="200"
label="Revenue Q$quarter" caption="" />
<textbox id="margin_q$quarter$" type="num" width="100"
label="Margin Q$quarter" caption="%" />
</hbox>
</for>

Example — Readonly computed field

XML
<textbox id="total" label="Total" type="num" width="200"
readonly="true">$($subtotal * (1 + $taxrate / 100))</textbox>

checkbox — Check box

Renders a two-state toggle. The content defines the value submitted when checked. When unchecked, the field is absent from EXTDATA (test with <if value1="$EXTDATA.myCheckbox" func="!=">). Key attributes: id, label, caption, selected, disabled.

Full reference →

Example — Simple option

XML
<checkbox id="newsletter" label="Subscribe" caption="Receive newsletter">1</checkbox>

Example — Dynamic checkbox group

A common pattern is generating checkboxes from data, using unique IDs:

XML
<title>Services</title>
<foreach var="services" var_value="service">
<replace pattern="[^A-Za-z0-9]" var="safeId">$service</replace>
<checkbox id="svc_$safeId$" caption="$service">$service</checkbox>
</foreach>

Example — Approval workflow

XML
<checkbox id="approved" caption="I approve this document"
disabled="$readonly">$session.name||$DATENOW</checkbox>

When checked, the value stored is a composite string like "John Doe||2026-02-08", recording both who approved and when.


listbox — Selection list

Renders a dropdown (type="single") or a scrollable checkbox list (type="multi"). Items are defined with <listitem> children. For multi-select, selected values are joined with the delimiter (default ", ") into a single string — use <split> or <decode:csv> to parse them back. Key attributes: id, label, type, width, required, disabled, caption (placeholder for single), height (for multi), delimiter (for multi).

Full reference →

listitem — List item

Defines a single option within a <listbox>. The content is the submitted value; the caption attribute is the display text (defaults to the value). Use selected="true" to pre-select.

Full reference →

Example — Static dropdown

XML
<listbox id="priority" label="Priority" width="200">
<listitem caption="Low">1</listitem>
<listitem caption="Medium" selected="true">2</listitem>
<listitem caption="High">3</listitem>
<listitem caption="Critical">4</listitem>
</listbox>

Example — Dynamic dropdown from database

XML
<db:select var_result="users" type="assoc">
<db:fields>
<db:field>name</db:field>
<db:field>firstname</db:field>
<db:field>lastname</db:field>
</db:fields>
<db:table>users</db:table>
</db:select>

<listbox id="assignee" label="Assignee" width="300" caption="Select a user...">
<foreach var="users" var_value="user">
<listitem caption="$user.firstname $user.lastname">$user.name</listitem>
</foreach>
</listbox>

Example — Multi-select with height

XML
<listbox id="categories" type="multi" label="Categories"
height="200" delimiter=",">
<foreach var="settings.categories" var_value="cat">
<listitem>$cat</listitem>
</foreach>
</listbox>

Example — Percentage selector with loop

XML
<listbox id="probability" label="Probability" width="150">
<for var="pct" from="0" to="100" step="10">
<listitem caption="$pct %">$($pct / 100)</listitem>
</for>
</listbox>

entitybox — Entity selector

A specialized selector for choosing a ZeyOS entity record (contact, account, ticket, etc.) by ID, with auto-complete search. Use the tag attribute to filter results. Key attributes: id, entity, tag, label, caption, placeholder, width, required, disabled.

Full reference →

Example — Contact and account selectors

XML
<hbox>
<entitybox id="contact_id" entity="contacts" label="Contact"
width="300" required="true" />
<entitybox id="account_id" entity="accounts" label="Company"
width="300" placeholder="Search company..." />
</hbox>

Example — Filtered entity selection

XML
<entitybox entity="contacts" id="vendor_id" tag="Vendor"
label="Vendor" width="300" required="true" />

Only contacts tagged "Vendor" appear in the search results.

Example — Dynamic entity type

XML
<listbox id="entityType" label="Entity Type" width="200">
<listitem caption="Projects">projects</listitem>
<listitem caption="Tickets">tickets</listitem>
<listitem caption="Transactions">transactions</listitem>
</listbox>

<if value1="$EXTDATA.entityType" func="!=">
<entitybox entity="$EXTDATA.entityType" id="entityIndex"
label="Record" width="300" />
</if>

Common layout patterns

Two-column form

XML
<hbox>
<vbox width="50%">
<textbox id="firstname" label="First Name" width="280" />
<textbox id="email" label="Email" type="email" width="280" />
<textbox id="phone" label="Phone" type="tel" width="280" />
</vbox>
<vbox width="50%">
<textbox id="lastname" label="Last Name" width="280" />
<textbox id="company" label="Company" width="280" />
<textbox id="position" label="Position" width="280" />
</vbox>
</hbox>

Sectioned form with dividers

XML
<title>General Information</title>
<hbox>
<textbox id="name" label="Name" width="300" required="true" />
<listbox id="status" label="Status" width="200">
<listitem>Active</listitem>
<listitem>Inactive</listitem>
</listbox>
</hbox>

<rule />

<title>Financial Details</title>
<hbox>
<textbox id="budget" label="Budget" type="money" width="200" caption="" />
<textbox id="currency" label="Currency" type="currency" width="150" />
</hbox>

<rule />

<title>Notes</title>
<textbox id="notes" label="Internal Notes" type="multi" height="150" />

Conditional form sections

XML
<if value1="$EXTDATA.approved" func="!=">
<!-- Already approved — show read-only summary -->
<description label="Approved by">$EXTDATA.approved_by</description>
<description label="Approved on">
<date:format format="d.m.Y">$EXTDATA.approved_date</date:format>
</description>
<else>
<!-- Not yet approved — show approval controls -->
<checkbox id="approve" caption="I approve this request">1</checkbox>
<textbox id="approve_comment" label="Comment" type="multi" height="100" />
</else>
</if>

Data-driven form generation

Generate form controls dynamically from configuration or database queries:

XML
<foreach var="APPSETTINGS.customFields" var_key="fieldId" var_value="field">
<switch value1="$field.type">
<case value="text">
<textbox id="cf_$fieldId" label="$field.label" width="300" />
</case>
<case value="number">
<textbox id="cf_$fieldId" label="$field.label" type="num"
width="200" caption="$field.unit" />
</case>
<case value="select">
<listbox id="cf_$fieldId" label="$field.label" width="300">
<foreach var="field.options" var_value="opt">
<listitem>$opt</listitem>
</foreach>
</listbox>
</case>
<case value="bool">
<checkbox id="cf_$fieldId" caption="$field.label">1</checkbox>
</case>
</switch>
</foreach>

Complete weblet example

A realistic weblet form for contract management, combining all form elements:

XML
<title>Contract Details</title>

<hbox>
<vbox width="50%">
<entitybox id="contact_id" entity="contacts" label="Contact"
width="300" required="true" />
<entitybox id="account_id" entity="accounts" label="Company"
width="300" />
<listbox id="contract_type" label="Type" width="300" required="true">
<listitem caption="Service Agreement">service</listitem>
<listitem caption="Maintenance Contract">maintenance</listitem>
<listitem caption="Consulting">consulting</listitem>
</listbox>
</vbox>
<vbox width="50%">
<textbox id="contract_num" label="Contract No." width="300"
readonly="true">$EXTDATA.contract_num</textbox>
<textbox id="start_date" label="Start Date" type="date"
width="200" required="true" />
<textbox id="end_date" label="End Date" type="date" width="200" />
</vbox>
</hbox>

<rule />

<title>Financial</title>

<hbox>
<textbox id="value" label="Contract Value" type="money"
width="200" caption="" />
<textbox id="currency" label="Currency" type="currency" width="150" />
<listbox id="billing_cycle" label="Billing Cycle" width="200">
<listitem>Monthly</listitem>
<listitem>Quarterly</listitem>
<listitem>Annually</listitem>
</listbox>
</hbox>

<rule />

<title>Services</title>

<listbox id="services" type="multi" label="Included Services"
height="150" delimiter=",">
<foreach var="APPSETTINGS.serviceOptions" var_value="svc">
<listitem>$svc</listitem>
</foreach>
</listbox>

<rule />

<title>Notes</title>

<textbox id="internal_notes" label="Internal Notes" type="multi"
height="150" />

<hbox>
<checkbox id="auto_renew" caption="Auto-renew contract">1</checkbox>
<checkbox id="notify_expiry" caption="Notify before expiry"
selected="true">1</checkbox>
</hbox>

<rule />

<if value1="$EXTDATA.approved">
<description label="Approved by">$EXTDATA.approved_by</description>
<description label="Date">
<date:format format="d.m.Y H:i">$EXTDATA.approved_date</date:format>
</description>
<else>
<description label="Status">Pending approval</description>
</else>
</if>