XMLUI Cheat Sheet
Properties
You can influence components' visual appearance (and behavior) by setting component properties.
Set a Simple Component Property
Component properties are represented with attributes in the markup. Set this attribute value with a literal string.
<Text value="I'm a text!" />
Set a component property with an expression
You can use expressions to set up a property value. Expressions are wrapped in curly braces (between {
and }
characters).
<!-- Displays: "Life, universe, and everything: 42" -->
<Text value="Life, universe, and everything: {6 * 7}" />
Set a component property with the <property>
helper tag and nested value
This construct is helpful when you want to set a property value to a component declaration (for example, you define a template with a property).
<Items data="{[1, 2, 3]}">
<property name="itemTemplate">
<Text value="This item is: {$item}" />
</property>
</Items>
Set component presence and visibility
By setting a component's when
attribute to false
, you can omit it from the markup tree (as if the definition were not there).
<Text when="false" value="I'm omitted from the markup" />
Naturally, components omitted from the markup (when
set to false
) are not visible.
Access exposed component properties
You can assign an identifier to the component with the id
attribute and use that to access its exposed properties.
<App>
<TextBox id="myTextBox" placeholder="Type something" />
<Text variant="title">You typed: {myTextBox.value}</Text>
</App>
This way, you can bind components: changing a particular property of one will trigger changing the other.
Invoke exposed component methods
You can assign an identifier to the component with the id
attribute and use that to invoke its exposed methods.
<App>
<Checkbox
id="myCheckbox"
label="Use encrypted channel"
initialValue="false" />
<Button label="Turn on encryption" onClick="myCheckbox.setValue(true)"/>
</App>
Expressions
The expressions in XMLUI use the same syntax and semantics as JavaScript. For details on syntax, see this article.
Use an expression in a property value or component text
Expressions are wrapped between curly braces; the engine evaluates them and replaces them with their actual value.
<App>
<Text value="{1 + 2 * 3}" /> <!-- Displays 7 -->
<Text>{6 * 7}</Text> <!-- Displays 42 -->
<Text value="{ 3 < 4}" /> <!-- Displays true -->
</App>
Use an expression for interpolation
You can use multiple expressions combined with literal string segments in property values or component text.
<App>
<Text value="10 times 10 is {10*10} and not {9 * 10}" />
</App>
Use curly braces in values
Use \{
as an escape for the opening curly brace. You do not need to escape the closing curly brace.
<Text value="\{1 + 2 * 3}" /> <!-- Displays {1 + 2 * 3} -->
Variables
Variable names start with a letter or an underscore (_
) and continue with these characters or digits.
Variables are scoped; their name must be unique in the declaring scope. When you declare variables in markup, they are visible within the declaring component (including all direct and indirect children). When you declare them in a code-behind file, their scope is the markup within the corresponding file.
Declare a variable with the var.
prefix
<App var.myVar="Hello, World!">
<Text>{myVar}</Text> <!-- Displays: Hello, World! -->
</App>
Declare a variable with the <variable>
helper tag and a nested value
<App>
<variable name="myVar">
Hello, World!
</variable>
<Text>{myVar}</Text> <!-- Displays: Hello, World! -->
</App>
Declare a variable in the code-behind file
var myVar="Hello, World!";
<App>
<Text>{myVar}</Text>
</App>
Reusing a variable name in a nested scope
The same variable name can be declared in nested scopes. The engine resolves the name to the variable in the closest (innermost) scope.
<App var.myVar="Hello, from App!">
<H1>{myVar}</H1> <!-- Displays: Hello, from App! -->
<VStack var.myVar="Hello, from VStack!">
<Text>{myVar}</Text> <!-- Displays: Hello, from VStack! -->
</VStack>
</App>
Leverage the reactive nature of variables
If you initialize them with an expression, the engine detects any changes on which the variable value depends. When a change happens, the engine refreshes the UI.
<App var.count="{0}" var.countTimes3="{3 * count}" >
<Button
label="Click to increment!"
onClick="count++" />
<Text>Click count = {count}</Text>
<Text>Click count * 3 = {countTimes3}</Text>
</App>
Any time count
is incremented, count3Times
follows the change and will always have the value of three times count.
Event Handlers
Declare an event handler with the on
attribute prefix
You can define an event handler for a particular component event using an attribute with the on
prefix followed by the event name:
<Button label="Click me" onClick="toast('Clicked!')" />
Declare an event handler with the <event>
helper tag and nested value
<Button label="Click me">
<event name="click">
toast('Clicked!')
</event>
</Button>
Declare an event handler in the code-behind file
You can assign the function's name declared in the code-behind file to the event handler in the markup.
function displayToast() {
toast('Clicked!');
}
<Button
label="Click me"
onClick="displayToast" />
Declare a code-behind event handler with auto markup-binding
When your component must have an id, and the event handler function name follows the [componentId]_on[eventName]
pattern, XMLUI automatically binds the event handler to the corresponding component.
function myButton_onClick() {
toast('Clicked!');
}
<Button
id="myButton"
label="Click me" />
Use auto-binding of event handlers with care. Though your markup is shorter, you must look into the code-behind file to check if a component declares a particular event handler.
Use an APICall
component as an event handler
The XMLUI engine supports using an APICall
component definition as an event handler. This option is available only with the component markup (not in the code-behind file) using the <event>
helper tag:
<Button label="Delete Customer">
<event name="click">
<APICall
url="/api/customer/12345"
method="delete"
confirmMessage="Are you sure you want to delete the customer?"
/>
</event>
</Button>
APICall
provides valuable services (such as confirmation before the invocation and many others). Learn more in this article.
Layout
XMLUI has a few fundamental components you can use to establish the app's layout. Their sole responsibility is to provide a viewport and organize the placement, dimensions, and other visual traits of their children.
Component | Description |
---|---|
App | This component provides a UI frame for XMLUI apps. According to predefined (and run-time configurable) structure templates, App  allows you to display your preferred layout. |
Stack | This component is a layout container displaying children in a horizontal or vertical stack. |
VStack , HStack | These components are specialized versions of Stack that display children in a vertical or horizontal stack, respectively. |
FlowLayout | This layout component is used to position content in rows with an auto wrapping feature: if the length of the items exceed the available space the layout will wrap into a new line. |
SpaceFiler | This component works in layout containers to fill the remaining (unused) space. Its behavior depends on the layout container in which it is used. |
Splitter | This component divides a container (such as a window, panel, pane, etc.) into two resizable sections. |
Fetching Data
Use a URL with the GET operation (list)
Setting the data
property of data-aware components (such as List
, Items
, Table
, and others) to a string fetches the data from the specified URL (with the GET verb).
<List data="/api/products">
<Card title="{$item.name}" subtitle="{$item.description}"/>
</List>
Use a URL with the GET operation (filtered list)
<App var.category="electronics">
<Button label="Use books" onClick="category = 'books'" />
<List data="/api/products/{category}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
Bind an input value with a URL
You can combine the value of a particular input with the URL.
<App>
<TextBox id="myTextBox" placeholder="Search value" />
<List data="/api/products?search={myTextBox.value}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
Use a URL with another verb
If you must use a verb other than GET, you can use a DataSource
that provides more control over the request. The identifier of the DataSource
is in the data
property.
<App>
<DataSource id="productSource" url="/api/products" method="post" />
<List data="{productSource}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
Use a request header
You can set a request header in a DataSource
component.
<App>
<DataSource
id="productSource"
url="/api/products"
headers="{{ 'x-api-key': 'my-secret-key' }}" />
<List data="{productSource}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
Select a part of the response as the result
If the data you want to use is just a part of the response, you can drill down to the response segment with your data.
<App>
<DataSource id="productSource" url="/api/products" resultSelector="items"/>
<List data="{productSource}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
This example assumes the response contains a metadata
property (to ignore) and an items
property (the actual payload for your query).
Filter or modify the fetched result
You can refer to the value
property of a DataSource
and use that to filter or modify the result.
<App>
<DataSource id="productSource" url="/api/products" resultSelector="items"/>
<List data="{productSource.value.filter(p => p.weight > 100)}" >
<Card title="{$item.name}" subtitle="{$item.description}" />
</List>
</App>
The markup in this example filters the product with a weight over 100 lbs.
Context variables
These are the key context variables available in XMLUI forms and components.
$data
- Scope: Available inside a
<Form>
and its children. - What it is: The current state of the form's data object (all fields/values).
- Usage:
- Read or display the entire form's data:
{JSON.stringify($data)}
- Read or display the entire form's data:
- Example:
<Text value="{JSON.stringify($data)}" />
$item
- Scope: Available inside components that iterate over lists, such as
<Table>
,<Items>
, or inside a FormItem of type "items". - What it is: The current item in the iteration (e.g., a row in a table, an option in a select, or a line item in an invoice).
- Usage:
- Access properties of the current item:
$item.name
,$item.price
- Access properties of the current item:
- Example:
<Table data="{clients}"> <Column bindTo="Name"> <Text>{$item.Name}</Text> </Column> </Table>
In forms:
$validationResult
- Scope: Inside a
FormItem
. - What it is: The result of the latest validation for the field.
- Example:
<FormItem bindTo="email"> <Text value="{JSON.stringify($validationResult)}" /> </FormItem>
$setValue
- Scope: Inside a
FormItem
. - What it is: A function to set the value of the field.
- Example:
<Button onClick="$setValue('new value')" label="Set Value" />
$value
- Scope: Inside a
FormItem
. - What it is: The current value of the field.
- Example:
<FormItem bindTo="name"> <Text value="{$value}" /> </FormItem>
In iterators:
$itemIndex
- Scope: Inside iterators (e.g.,
<Items>
,<Table>
, or FormItem of type "items"). - What it is: The current index in the array.
- Example:
<Items data="{products}"> <Text>Index: {$itemIndex}, Name: {$item.name}</Text> </Items>
In event handlers:
$param
- Scope: Available in event handlers, especially in
<event name="submit">
or API calls. - What it is: The data passed to the event or API call, often the form data at the time of submission.
In components:
var.myVar
- Scope: Declared in markup with
var.
prefix; available in the declaring component and its children. - What it is: A scoped variable.
- Example:
<App var.count="{0}"> <Button onClick="count++" label="Increment" /> <Text>Count: {count}</Text> </App>
myComponentId
- Scope: Any component with an
id
attribute. - What it is: Reference to the component instance, allowing access to its properties and methods.
- Example:
<TextBox id="myTextBox" /> <Button onClick="myTextBox.setValue('Hello!')" label="Set Value" /> <Text value="{myTextBox.value}" />
Summary
Variable | Scope/Context | What it Represents |
---|---|---|
$data | Inside <Form> | The form's current data object |
$item | Inside iterators | The current item in a list/array |
$param | In event handlers | The event's payload (e.g., form data) |
$itemIndex | Inside iterators | The current index in a list/array |
$validationResult | In FormItem | Result of latest validation |
$setValue | In FormItem | Function to set the value |
$value | In FormItem | The current value |
var.myVar | Declared in markup | A scoped variable |
myComponentId | Component with id | Reference to the component instance |
Calling an API
TBD
Using Forms
TBD
Dialogs
TBD
Creating App-Specific components
TBD
Using Themes
TBD