XML Markup
When you write XML markup to create an XMLUI app, you use XML tags to name components. And you use XML attributes to set properties that govern their behavior.
Properties
An attribute may be a literal string that sets the value of a property.
<Text value="This is rendered as text." />
A literal property
<Text value="This is rendered as text." />
Expressions
An attribute may also be a JavaScript expression — enclosed in curly braces
{ }
— that dynamically sets the value of a property.<Text value="Life, the universe, and everything: { 6 * 7 }" />
A dynamic property
<Text value="Life, the universe, and everything: { 6 * 7 }" />
An expression can hold a JSON list.
<Items data="{ ['Bakerloo', 'Central', 'Circle'] }" >
<Text>{ $item }</Text>
</Items>
A JSON list
<Items data="{ ['Bakerloo', 'Central', 'Circle'] }" >
<Text>{ $item }</Text>
</Items>
Or a complex JSON object, in which case you'll write an outer set of curly braces to introduce the expression and an inner set to define an object like this form's
data
property.<App>
<Form id="searchForm" padding="0.5rem"
data='{ { station: "Brixton", wifi: true, toilets: false } }'
onSubmit="() => { preview.setValue(JSON.stringify($data)) }"
>
<Text>Search for station amenities</Text>
<HStack verticalAlignment="center" >
<FormItem bindTo="station" />
<FormItem
type="checkbox"
label="wifi"
bindTo="wifi"
labelPosition="start"
/>
<FormItem
type="checkbox"
label="toilets"
bindTo="toilets"
labelPosition="start"
/>
</HStack>
<property name="buttonRowTemplate">
<Button type="submit" icon="search" label="Search"/>
</property>
</Form>
<TextArea id="preview" />
</App>
A complex JSON object
<App>
<Form id="searchForm" padding="0.5rem"
data='{ { station: "Brixton", wifi: true, toilets: false } }'
onSubmit="() => { preview.setValue(JSON.stringify($data)) }"
>
<Text>Search for station amenities</Text>
<HStack verticalAlignment="center" >
<FormItem bindTo="station" />
<FormItem
type="checkbox"
label="wifi"
bindTo="wifi"
labelPosition="start"
/>
<FormItem
type="checkbox"
label="toilets"
bindTo="toilets"
labelPosition="start"
/>
</HStack>
<property name="buttonRowTemplate">
<Button type="submit" icon="search" label="Search"/>
</property>
</Form>
<TextArea id="preview" />
</App>
In addition to a literal string or an expression, you will sometimes use the special tag<property>
to set a value using markup, like theButtonRowTemplate
that defines this form's button.
Variables
A component may declare a variable that's visible to itself and its children. Variable names start with a letter or an underscore (
_
) and continue with these characters or digits.You can declare a variable using the
var
prefix.<App var.stations="{ [ 'Bakerloo', 'Central', 'Circle'] }">
<Items data="{stations}">
<Text> {$item} </Text>
</Items>
</App>
Declaring a variable with var
<App var.stations="{ [ 'Bakerloo', 'Central', 'Circle'] }">
<Items data="{stations}">
<Text> {$item} </Text>
</Items>
</App>
Or using the
<variable>
helper tag.<App>
<variable
name="stations"
value="{ [ 'Bakerloo', 'Central', 'Circle'] }" />
<Items data="{stations}">
<Text>{$item}</Text>
</Items>
</App>
Declaring a variable with <variable>
<App>
<variable
name="stations"
value="{ [ 'Bakerloo', 'Central', 'Circle'] }" />
<Items data="{stations}">
<Text>{$item}</Text>
</Items>
</App>
Nested variables
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.title="var.title is 'Hello, from App!'">
<H1>{title}</H1>
<VStack var.title="var.title is 'Hello, from VStack'!">
<Text>{title}</Text>
</VStack>
</App>
Defining and using nested variables
<App var.title="var.title is 'Hello, from App!'">
<H1>{title}</H1>
<VStack var.title="var.title is 'Hello, from VStack'!">
<Text>{title}</Text>
</VStack>
</App>
Reactive variables
In Reactive data binding we saw how a
Select
can cause a Table
to refresh by setting the url
property of the DataSource
on which the Table
depends. Here's a more basic example of how components interact with reactive variables.<App var.count="{0}" var.countTimes3="{3 * count}" >
<Button
label="Click to increment the count"
onClick="count++" />
<Text>Click count = {count} (changes directly)</Text>
<Text>Click count * 3 = {countTimes3} (changes indirectly)</Text>
</App>
Defining and using reactive variables
<App var.count="{0}" var.countTimes3="{3 * count}" >
<Button
label="Click to increment the count"
onClick="count++" />
<Text>Click count = {count} (changes directly)</Text>
<Text>Click count * 3 = {countTimes3} (changes indirectly)</Text>
</App>
The
Button
's click handler increments count
directly. But because countTimes3
is define using an expression that refers to count
, the engine reevalautes that expression each time count
changes and updates countTimes3
indirectly.We've seen two ways to declare variables: a
var
declaration in an XML attribute, or the variable
tag. A similar pattern applies to event handlers. The Button
to increment the count declares its handler in an attribute whose name combines the on
prefix with the name click. You may also use the <event>
helper tag with no prefix for the event name.<App var.count="{0}" >
<Button label="Click me! Click count = {count}">
<event name="click">
{ count++ }
</event>
</Button>
</App>
Declare an event handler using the <event> tag
<App var.count="{0}" >
<Button label="Click me! Click count = {count}">
<event name="click">
{ count++ }
</event>
</Button>
</App>
Why use the<event>
tag? In this example there's no reason to prefer it. But as we saw above, you declare aForm
'sbuttonRowTemplate
property in XMLUI markup using the<property>
helper tag. The same pattern applies when a button's handler is an XMLUI component like<APICall>
.<Button label="Click to increment the count on the server"> <event name="click"> <APICall url="/count/increment" /> </event> <Text>Click count = {count}</Text> </Button>