Previous chapter | Next chapter
So far, in our example, we have always had just one control each entry; for first and last name, address fields, and so on. But in some cases, we may want to offer multiple controls. For instance:
In each of these cases, there is no predefined maximum number that we would want to set, although a minimum of one for phone number and email address would be logical.
How do we go about this?
First of all, we have to make provisions in the model; we provide a <activities/> node in the instance.
Then, in the form, we add a group element, and inside it we place a repeat control.
<!-- This group will collect some information about the event -->
<xf:group>
<xf:label>Activities</xf:label>
<xf:repeat id="repeater" nodeset="activities/activity" appearance="compact">
<xf:input ref=".">
<xf:label>Description</xf:label>
</xf:input>
<xf:trigger class="red">
<xf:label>Delete this activity</xf:label>
<xf:delete nodeset="." at="1" if="count(//activity) > 1" ev:event="DOMActivate" />
</xf:trigger>
</xf:repeat>
<xf:trigger class="green">
<xf:label>Add an activity</xf:label>
<xf:insert nodeset="activities/activity" at="count(//activiry)" position="after" ev:event="DOMActivate" />
</xf:trigger>
</xf:group>
The net result of the above code is displayed below. Initially, one Description line is available (because in the instance there is one <activity /> node present).
When we click on the “Add an activity” trigger, we see another row appear (and a matching node in the instance).
The “Delete this activity” does exactly what it promises. It removes the Description line and the corresponding <activity /> node in the instance.
Of course, inside a repeat element we can group as many controls as we would like and apply all relevant validations.
Let us zoom in a little bit on the two triggers.
Both of them manipulate the model instance by either removing or adding an <activity /> node. After the instance has been manipulated, an event is raised. This DOMActivate event will cause the form to be rendered again so as to be in accordance again with the instance (which resides server-side, as you my remember).
Note that an activity can only be removed if there are more than one activities. This guarantees that at least one activity input possibility will always be available.
This repeat function is also convenient for multiple uploads. When we use the browser file selector to select an upload, we can always just select a single file (a security feature). By using a repeat, we can offer as many uploads as required by the user (with some practical limit maybe).