What can be learned here:
<fx-repeat>
elementLet’s go for a bit more fancy example - a simple todo app - and learn about some new elements.
In this tutorial we add some real interaction, give some feedback messages to the user and actually change our data.
It will introduce you to <fx-repeat>
element that is one of the container
elements available in Fore.
For our todo app we’d like to have a list of todos along with a completion and a due date.
Our data model for a single todo looks like this:
<task complete="" due=""></task>
Lets put that into Fore and add some dummy data to play with.
<fx-fore>
<fx-model id="record">
<fx-instance>
<data>
<task complete="false" due="2022-06-05">Make tutorial part 1</task>
<task complete="false" due="2022-06-15">Pick up Milk</task>
</data>
</fx-instance>
</fx-model>
</fx-fore>
<fx-repeat>
For displaying a list of todos we’ll use the <fx-repeat>
element
which will show all todos in a list.
We add the repeat alongside the model in our markup.
<fx-fore>
<fx-model id="record">
<fx-instance>
<data>
<task complete="false" due="2022-06-05">Make tutorial part 1</task>
<task complete="false" due="2022-06-15">Pick up Milk</task>
</data>
</fx-instance>
</fx-model>
<h1>My Todos</h1>
<fx-repeat id="task" ref="task">
<template>
<div>{.}</div>
</template>
</fx-repeat>
</fx-fore>
ref
AttributeThe ref
attribute is used throughout Fore on many elements. It uses
binding expressions to link to some data node.
In our case the binding expression is simply ’task’ and will point to task
elements
in our data.
<fx-fore>
<fx-model id="record">
<fx-instance>
<data>
<task complete="false" due="2022-06-05">Make tutorial part 1</task>
<task complete="false" due="2022-06-15">Pick up Milk</task>
</data>
</fx-instance>
</fx-model>
<h1>My Todos</h1>
<fx-repeat id="task" ref="task">
<template>
<div>{.}</div>
</template>
</fx-repeat>
</fx-fore>
Result so far
A repeat always has a <template>
child which is the blueprint for rendering
one bound item.
It just contains a div and the Template Expression of ‘{.}’.
"." means the current node which is the bound task
node.
This is known as ‘scoped resolution’ and means that binding expressions
are always evaluated relatively to their parent binding expression (aka ref
attributes).
In this step we add some controls to the repeat template.
Fore uses a generic <fx-control>
element to bind a concrete widget (like a native <input>
)
to the model.
This has the advantage that there’s no need for a big list of different controls to be supported but instead just use existing ones.
In this example simple native browser input controls are used.
<fx-fore>
<fx-model id="record">
<fx-instance>
<data>
<task complete="false" due="2022-06-05">Make tutorial part 1</task>
<task complete="false" due="2022-06-15">Pick up Milk</task>
</data>
</fx-instance>
</fx-model>
<h1>My Todos</h1>
<fx-repeat id="task" ref="task">
<template>
<div>
<fx-control ref="@complete" value-prop="checked" update-event="input">
<input type="checkbox">
</fx-control>
<fx-control class="{@complete}" id="task" ref="."></fx-control>
<fx-control ref="@due">
<input type="date">
</fx-control>
<fx-trigger class="btn delete">
<button>x</button>
<fx-delete ref="."></fx-delete>
</fx-trigger>
</div>
</template>
</fx-repeat>
</fx-fore>
Note the second <fx-control>
which is empty. If no control
is given as child it will default to a <input type="text">
control which is
auto-created to save some typing.
Here 3 <fx-control>
s and 2 <fx-trigger>
elements have been added.
The controls bind to the respective nodes in the data and use:
The ‘@’ character addresses an attribute of an XML node. Scoped resolution will result in the binding expression ’task[1]/@complete’ for the first todo.
<fx-fore>
<fx-model id="record">
<fx-instance>
<data>
<task complete="false" due="2022-06-05">Make tutorial part 1</task>
<task complete="false" due="2022-06-15">Pick up Milk</task>
</data>
</fx-instance>
</fx-model>
<h1>My Todos
<fx-trigger class="btn add">
<button>add</button>
<fx-insert ref="task" at="1" position="before"></fx-insert>
</fx-trigger>
</h1>
<fx-repeat id="task" ref="task">
<template>
<div>
<fx-control ref="@complete" value-prop="checked" update-event="input">
<input class="widget" type="checkbox">
</fx-control>
<fx-control class="{@complete}" id="task" ref="."></fx-control>
<fx-control ref="@due">
<input type="date">
</fx-control>
<fx-trigger class="btn delete">
<button>delete</button>
<fx-delete ref="."></fx-delete>
</fx-trigger>
</div>
</template>
</fx-repeat>
</fx-fore>
The first <fx-trigger>
is contained within the <h1>
and inserts
a new todo at the top of the list.
The <fx-trigger>
within the repeat will display a button and allow to delete a todo from the list
with the <fx-delete>
action.
This is the barebones of the todo app. Next chapter will introduce some refinements.