A repeating structure usually involves defining a list of items to 'repeat over' (or iterate) and a template to be applied to each item in the list.
In many systems the template part would need to be defined with a separate file, and although there will be certain situations where this is a good approach, there are also plenty of situations where it's just that bit too much work for the simple job in hand.
The XForms repeat element allows us to specify both the list and template in one. The items that make up the list are expressed using an XPath expression, and the template is defined by placing mark-up inside repeat. (The mark-up can be anything, including further repeat elements.)
For the Flickr form we want a repeating structure that has as many entries as there are photo items in the returned XML. The XPath to create a list of photo items is:
instance('inst-rs')/photos/photo
We can use this expression to set up a repeating structure that operates on each returned photo, by adding the following to the form just after the output that shows any error results:
</xf:output>
<xf:repeat nodeset="instance('inst-rs')/photos/photo">
[...]
</xf:repeat>
</xf:group>The template is created from any tags that are inside the repeat element itself, and can include any HTML and XForms tags, including the repeat element. A moment ago we set the template to a simple ellipsis:
<xf:repeat nodeset="instance('inst-rs')/photos/photo">
[...]
</xf:repeat>This will give us enough to test with, so save and refresh the form, and try searching for something--you should see as many ellipses as there are search results:
Now that we know that both the search and our repeat are working fine, let's fill out the repeat template.
We'll first use a simple output control to show the title of each of the photos returned from Flickr, before we then move on to show how to display the actual image.
The XML item that holds this data is the title attribute on each photo element. The XPath expression needed to refer to, say, the title of the third photo would be:
instance('inst-rs')/photos/photo[3]/@titleHowever, when we place controls into a repeat template, their XPath expressions are evaluated one at a time, in the context of each of the items in the list. So to show the title of each of the photos in the list, we need only do this:
<xf:repeat nodeset="instance('inst-rs')/photos/photo">
[<xf:output ref="@title" />]
</xf:repeat>Refresh the form, and try searching for something--you should see a list of image titles: