- From: John Boyer <boyerj@ca.ibm.com>
- Date: Mon, 23 Jul 2007 20:24:19 -0400
- To: ebruchez@orbeon.com
- Cc: "Forms WG (new)" <public-forms@w3.org>
- Message-ID: <OFEFF63C05.12E7F62F-ON88257321.005E59D9-88257322.00023ABC@ca.ibm.com>
Hi Erik, The adjustment you made for repeat index looks good, though I do also have an outstanding LC comment that questions why on earth are we retaining the part immediately afterward that resets the indexes of inner repeats. So I adjusted step 8 of insert and step 5 of delete to show what the spec changes would be if we got rid of inner repeat index reinitialization. Regarding the minor issue you raised that insert context is restricted to being an element, note that this was done to simplify some of the later decision points around choosing a target location. So, I preserved your change, but felt it necessary to change part 6 to accommodate. Regarding removal of step 6B, that's good, but it contained a fix we made at the FtF, so I had to adjust step 6 to accommodate for it since otherwise you would get down to the end of step 6 and not have accounted for the attribute order problem. Turned out to be easiest just to deal with attributes in 6a. It also seemed necessary to move the root node material to 6B, then do the general case in the remainder of the step. It really looks simpler now, esp. since we did delete that old step 6B that you wanted to remove, so please have a look through it. Also, have a look at step 8 of insert and step 5 of delete and let me know what you think about the inner repeat index reinitialization issue. Finally, I'll get back to you about removing "homogeneous collection". Frankly, I would rather it if you could take on the task of writing the better examples people want for insert and delete. I think that would be more valuable to the WG as you are immersed in this issue right now. I have a clear idea of what the WG wants changed, so it's not too ambiguous a task. Are you amenable to taking it on? Cheers, John M. Boyer, Ph.D. STSM: Lotus Forms Architect and Researcher Chair, W3C Forms Working Group Workplace, Portal and Collaboration Software IBM Victoria Software Lab E-Mail: boyerj@ca.ibm.com Blog: http://www.ibm.com/developerworks/blogs/page/JohnBoyer Erik Bruchez <ebruchez@orbeon.com> Sent by: public-forms-request@w3.org 07/17/2007 03:25 PM Please respond to ebruchez@orbeon.com To "Forms WG (new)" <public-forms@w3.org> cc www-forms-editor@w3.org Subject Updates to section "9.3.5 The insert Action" All, I integrated the suggestions from the following messages into this section: Issues with point 6b of insert action http://lists.w3.org/Archives/Member/w3c-forms/2007JanMar/0111.html Minor Issue with point 1 of insert action http://lists.w3.org/Archives/Member/w3c-forms/2007JanMar/0113.html xforms:index and repeat index updates http://lists.w3.org/Archives/Member/w3c-forms/2007JanMar/0115.html Unless I am mistaken, with the exception of the "attribute position" issue which was already handled at the last f2f, the above messages contain the issues with xforms:repeat which I had the green light to integrate into the spec. John, I attach my modified ui.xml with diff marks. This is based off a bundle I downloaded on Tuesday. I note that the text still contains references to homogeneous collections. Did you plan to remove this, or should I do it as well? Thanks, -Erik -- Orbeon Forms - Web Forms for the Enterprise Done the Right Way http://www.orbeon.com/ <?xml version="1.0" encoding="UTF-8"?><div1 id="ui"> <head>XForms User Interface</head> <p>This chapter covers XForms features for combining <termref def="def-form-control">form control</termref>s into user interfaces.</p> <div2 id="ui-group-module"> <head>The XForms Group Module</head> <p> All form controls defined in <specref ref="controls"/> are treated as individual units for purposes of visual layout e.g., in XHTML processing. Aggregation of form controls with markup defined in this chapter provides semantics about the relationship among user interface controls; such knowledge can be useful in delivering a coherent UI to small devices. For example, if the user interface needs to be split up over several screens, controls appearing inside the same aggregation would typically be rendered on the same screen or page. The elements and attributes included in this module are:</p> <table border="1" summary="listing of XForms Group elements, attributes, and content models"> <tbody> <tr> <th>Element</th> <th>Attributes</th> <th>Minimal Content Model</th> </tr> <tr> <td><termref def="ui-group">group</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</td> <td>label?, ((<termref def="elems-form-controls">Form Controls</termref>)|group|switch|repeat|<termref def="elems-ui-common">UI Common</termref>)*</td> </tr> </tbody> </table> <div3 id="ui-group"> <head>The group Element</head> <p>The <el>group</el> element is used as a container for defining a hierarchy of form controls. Groups can be nested to create complex hierarchies. A group is considered to be non-relevant if and only if:</p> <ulist> <item><p>the Single Node Binding is expressed and resolves to empty nodeset,</p></item> <item><p>the Single Node Binding is expressed and resolves to a non-relevant instance node,</p></item> <item><p>the <el>group</el> is contained by a non-relevant <el>switch</el> or <el>group</el> (which includes a non-relevant <el>repeat</el> item), or</p></item> <item><p>the <el>group</el> is contained by a non-selected <el>case</el> element of a <el>switch</el>.</p></item> </ulist> <p>All content elements (e.g. form controls, groups, switches, repeats and host language content) within a non-relevant group are handled as non-relevant. When a <el>group</el> becomes non-relevant, it must receive event <code>xforms-disabled</code> and then the XForms action handlers that are listening for events on the non-relevant <el>group</el> must be disabled. When a non-relevant <el>group</el> changes to being relevant, the XForms action handlers that listen for events on the <el>group</el> must become enabled and then the <el>group</el> must receive the event <code>xforms-enabled</code>.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</p> <note> <p>If a group is non-relevant, then the rendering approach used to signify non-relevance is applied to the entire content of the group.</p> </note> <p>The optional <el>label</el> element has special significance when it appears as the first element child of <el>group</el>, representing a label for the entire group.</p> <p>Example:</p> <example> <head>Grouping Related Controls</head> <eg xml:space="preserve"><group ref="address"> <label>Shipping Address</label> <input ref="line_1"> <label>Address line 1</label> </input> <input ref="line_2"> <label>Address line 2</label> </input> <input ref="postcode"> <label>Postcode</label> </input> </group></eg> </example> <p>Setting the input focus on a group results in the focus being set to the first form control in the navigation order within that group.</p> </div3> </div2> <div2 id="ui-switch-module"> <head>The XForms Switch Module</head> <p>This section defines a switch construct that allows the creation of user interfaces where the user interface can be varied based on user actions and events. The elements and attributes included in this module are:</p> <table border="1" summary="listing of XForms Switch elements, attributes, and content models"> <tbody> <tr> <th>Element</th> <th>Attributes</th> <th>Minimal Content Model</th> </tr> <tr> <td><termref def="ui-switch">switch</termref></td> <td> <termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</td> <td>case+</td> </tr> <tr> <td><termref def="ui-case">case</termref></td> <td><termref def="structure-attrs-common">Common</termref>, selected (xsd:boolean)</td> <td>label?, ((<termref def="elems-form-controls">Form Controls</termref>)|<termref def="action-content-set">Action</termref>|group|switch|repeat)*</td> </tr> <tr> <td><termref def="action-toggle">toggle</termref></td> <td><termref def="structure-attrs-common">Common</termref><phrase diff="add">, <termref def="action-xmlevents">Events</termref>, <termref def="attrs-action-common">Action Common</termref></phrase>, case (xsd:IDREF)</td> <td>case?</td> </tr> </tbody> </table> <div3 id="ui-switch"> <head>The switch Element</head> <p> This element contains one or more <el>case</el> elements, any one of which is rendered at a given time.</p> <note> <p>This is separate from XForms <code>relevant</code> processing (see <specref ref="model-prop-relevant"/>), which is based on the current state of the XForms Model. As an example, portions of a questionnaire pertaining to the user's automobile may become relevant only if the user has answered in the affirmative to the question 'Do you own a car?'.</p> </note> <p>The non-relevance of a switch is determined in the same way as it is for <el>group</el> and similarly applies to the entire content. Also, as with <el>group</el>, when a <el>switch</el> becomes non-relevant, it must receive event <code>xforms-disabled</code> and then the XForms action handlers that are listening for events on the non-relevant <el>switch</el> must be disabled. As well, when a non-relevant <el>switch</el> changes to being relevant, the XForms action handlers that listen for events on the <el>switch</el> must become enabled and then the <el>switch</el> must receive the event <code>xforms-enabled</code>.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</p> <p>Example:</p> <example> <head>switch</head> <eg xml:space="preserve"><switch> <case id="in" selected="true"> <input ref="yourname"> <label>Please tell me your name</label> <toggle ev:event="DOMActivate" case="out"/> </input> </case> <case id="out" selected="false"> <html:p>Hello <output ref="yourname" /> <trigger id="editButton"> <label>Edit</label> <toggle ev:event="DOMActivate" case="in"/> </trigger> </html:p> </case> </switch></eg> </example> <p>The above results in the portion of the user interface contained in the first <code>case</code> being displayed initially. This prompts for the user's name; filling in a value and <emph>activating</emph> the control e.g., by pressing <code>enter</code> results switches to the alternate case, with a read-only <code>output</code> rendering. Activating the trigger labeled "Edit" in turn switches back to the original case.</p> </div3> <div3 id="ui-case"> <head>The case Element</head> <p>This element encloses markup to be conditionally rendered. The content elements (e.g. form controls, groups, switches, repeats and host language elements) within a non-selected <el>case</el> behave as if they were in a non-relevant <el>group</el> (see <specref ref="ui-group"/>). Similarly, content elements in a <el>case</el> that becomes selected behave as if they were in a <el>group</el> that has become relevant. The attribute <att>selected</att> determines the initial selected state.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref></p> <p>Special Attributes:</p> <glist> <gitem> <label>selected</label> <def> <p>Optional selection status for the case. The default value is "false".</p> </def> </gitem> </glist> <p>If multiple <el>case</el>s within a <el>switch</el> are marked as <code>selected="true"</code>, the first selected <el>case</el> remains and all others are deselected. If none are selected, the first becomes selected.</p> </div3> <div3 id="action-toggle"> <head>The toggle Element</head> <p>This XForms Action selects one possible case from an exclusive list of alternatives in a <el>switch</el>.</p> <!-- <p>This action adjusts all <el>selected</el> states (not the attribute values) on the affected <el>case</el>s to reflect the new state of the <el>switch</el> containing the identified <el>case</el>, and then performs the following:</p> <olist> <item> <p>Dispatching an <code>xforms-deselect</code> event to the currently selected <el>case</el>.</p> </item> <item> <p> Dispatching an <code>xform-select</code> event to the <el>case</el> to be selected.</p> </item> </olist> --> <p>This action performs the following:</p> <olist> <item> <p>Dispatches an <code>xforms-deselect</code> event to the currently selected <el>case</el> in the <el>switch</el> containing the identified <el>case</el>.</p> </item> <item> <p>Adjusts the <code>selected</code> states (not the attribute values) on the affected cases to reflect the new state of the <el>switch</el> containing the identified <el>case</el>.</p> </item> <item> <p>Dispatches an <code>xform-select</code> event to the <el>case</el> just selected.</p> </item> </olist> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref><phrase diff="add">, <termref def="attrs-action-common">Action Common</termref></phrase></p> <p>Special Attributes:</p> <glist> <gitem> <label>case</label> <def> <p>Optional reference to a <el>case</el> element. The <termref def="ui-case">case</termref> to select is specified by this attribute or by the child element <termref def="action-toggle-case">case</termref>.</p> </def> </gitem> </glist> <p>The <el>case</el> to be selected by the <el>switch</el> is identified by IDREF either by the attribute <att>case</att> or by a child <termref def="action-toggle-case">case</termref> element.</p> <div4 id="action-toggle-case"> <head>The case Element Child of the toggle Element</head> <p>This section defines a child element of <el>toggle</el> named <el>case</el> that is an alternative means of providing the identity of a <termref def="ui-case">case</termref> element to select with a <termref def="ui-switch">switch</termref>.</p> <p>Element: <el>case</el></p> <p>Common attributes: None</p> <p>Special Attributes:</p> <glist> <gitem> <label>value</label> <def> <p>Optional attribute containing an XPath expression to evaluate using the in-scope evaluation context. To obtain the <termref def="ui-case">case</termref> identity, the result of the expression is processed as if by call to the XPath <code>string</code> function.</p> </def> </gitem> </glist> <p>The <termref def="ui-case">case</termref> to be selected by the <el>toggle</el> action is given by the <att>case</att> attribute or the <el>case</el> element. If both are given, the element takes precedence. Due to the addition of the element, the <att>case</att> attribute is no longer required, but either the <att>case</att> attribute or the <el>case</el> element must appear. The <el>case</el> element can provide the identity of a <termref def="ui-case">case</termref> with either its string content or the <att>value</att> attribute. If both are given, then the <att>value</att> attribute takes precedence.</p> <example> <eg><toggle> <case value="concat('case_', ../addressBlockType)"/> </toggle></eg> </example> <note> <p>Whether the IDREF is obtained from the <att>case</att> attribute or element, the IDREF may not uniquely identify the desired <termref def="ui-case">case</termref> if the <el>case</el> element bearing the matching ID resides in a repeating construct such as element <el>repeat</el>. The general method described in <specref ref="idref-resolve"/> is used to determine the desired run-time case object.</p> </note> </div4> </div3> </div2> <div2 id="ui-repeat-module"> <head>The XForms Repeat Module</head> <p> The XForms specification allows the definition of repeating structures such as multiple items within a purchase order. When defining the XForms Model, such higher-level collections are constructed out of basic building blocks; similarly, this section defines user interface construct <el>repeat</el> that can bind to data structures such as lists and collections. The elements and attributes included in this module are:</p> <table border="1" summary="listing of XForms Repeat elements, attributes, and content models"> <tbody> <tr> <th>Element</th> <th>Attributes</th> <th>Minimal Content Model</th> </tr> <tr> <td><termref def="ui-repeat">repeat</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-nodeset">Node Set Binding</termref>, startindex (xsd:positiveInteger), number (xsd:nonNegativeInteger)</td> <td>((<termref def="elems-form-controls">Form Controls</termref>)|group|switch|repeat)*</td> </tr> <tr> <td><termref def="ui-common-elements-itemset">itemset</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="structure-attrs-nodeset">Node Set Binding</termref></td> <td>label, (value|copy), (<termref def="elems-ui-common">UI Common</termref>)*</td> </tr> <tr> <td><termref def="ui-adv-copy">copy</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</td> <td>EMPTY</td> </tr> <tr> <td><termref def="action-insert">insert</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref><phrase diff="add">, <termref def="attrs-action-common">Action Common</termref></phrase>, <termref def="structure-attrs-nodeset">Node Set Binding</termref>, at (<phrase diff="add">number </phrase> XPath Expression), position ("before"|"after")</td> <td>EMPTY</td> </tr> <tr> <td><termref def="action-delete">delete</termref></td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref><phrase diff="add">, <termref def="attrs-action-common">Action Common</termref></phrase>, <termref def="structure-attrs-nodeset">Node Set Binding</termref>, at (<phrase diff="add">number </phrase> XPath Expression)</td> <td>EMPTY</td> </tr> <tr> <td> <termref def="action-setindex">setindex</termref> </td> <td><termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref><phrase diff="add">, <termref def="attrs-action-common">Action Common</termref></phrase>, repeat (xsd:IDREF), index (<phrase diff="add">number </phrase> XPath Expression)</td> <td>EMPTY</td> </tr> <tr> <td>(various)</td> <td>[repeat-nodeset, repeat-bind, repeat-model] (Node Set Binding attributes), repeat-startindex (xsd:positiveInteger), repeat-number (xsd:nonNegativeInteger)</td> <td>N/A</td> </tr> </tbody> </table> <div3 id="ui-repeat"> <head>The repeat Element</head> <p id="defn-homogeneous">This element defines a UI mapping over a <term>homogeneous collection</term> selected by Node Set Binding Attributes. This node-set must consist of contiguous child element nodes, with the same local name and namespace name of a common parent node. The behavior of element <el>repeat</el> with respect to non-homogeneous node-sets is undefined.</p> <p>For example:</p> <example> <head>Shopping Cart</head> <eg xml:space="preserve"><repeat nodeset="/cart/items/item"> <input ref="." ...> <label>...</label> </input> <html:br/> </repeat></eg> </example> <p> Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="attrs-ui-common">UI Common</termref>, <termref def="structure-attrs-nodeset">Node Set Binding</termref></p> <p>Special Attributes:</p> <glist> <gitem> <label>startindex</label> <def> <p>Optional 1-based initial value of the repeat index. The default value is 1.</p> </def> </gitem> <gitem> <label>number</label> <def> <p>Optional hint to the XForms Processor as to how many elements from the collection to display. </p> </def> </gitem> </glist> <p>This element operates over a homogeneous collection by binding the encapsulated user interface controls to each element of the collection. If an element of the collection is non-relevant, then the rendering approach used to signify non-relevance is applied to the associated user interface controls. Attributes on this element specify how many members of the collection are presented to the user at any given time. XForms Actions <el>insert</el>, <el>delete</el>, and <el>setindex</el> can be used to operate on the collectionâ??see <specref ref="action"/>. Another way to view repeat processing (disregarding special user interface interactions) is to consider "unrolling" the repeat. The above example is similar to the following (given four <el>item</el> elements in the returned node-set):</p> <example> <head>Repeat Unrolled</head> <eg xml:space="preserve"><!-- unrolled repeat --> <input ref="/cart/items/item[1]"><label>...</label></input><html:br/> <input ref="/cart/items/item[2]"><label>...</label></input><html:br/> <input ref="/cart/items/item[3]"><label>...</label></input><html:br/> <input ref="/cart/items/item[4]"><label>...</label></input><html:br/></eg> </example> <example> <head>Homogeneous Collection</head> <eg xml:space="preserve"><model> <instance> <my:lines> <my:line name="a"> <my:price>3.00</my:price> </my:line> <my:line name="b"> <my:price>32.25</my:price> </my:line> <my:line name="c"> <my:price>132.99</my:price> </my:line> </my:lines> </instance> </model> ... <repeat id="lineset" nodeset="/my:lines/my:line"> <input ref="my:price"> <label>Line Item</label> </input> <input ref="@name"> <label>Name</label> </input> </repeat> <trigger> <label>Insert a new item after the current one</label> <action ev:event="DOMActivate"> <insert nodeset="/my:lines/my:line" at="index('lineset')" position="after"/> <setvalue ref="/my:lines/my:line[index('lineset')]/@name"/> <setvalue ref="/my:lines/my:line[index('lineset')]/price">0.00</setvalue> </action> </trigger> <trigger> <label>remove current item</label> <delete ev:event="DOMActivate" nodeset="/my:lines/my:line" at="index('lineset')"/> </trigger></eg> </example> </div3> <div3 id="ui.repeat.via.attrs"> <head>Creating Repeating Structures Via Attributes</head> <p> Element <el>repeat</el> enables the creation of user interfaces for populating repeating structures. When using XForms within host languages like XHTML, it is often necessary to create repeating structures within constructs such as <el>table</el>. Thus, one might wish to use element <el>repeat</el> within a <el>table</el> to create the rows of a table, where each row of the table binds to a distinct member of a homogeneous collection. Since <el>html:table</el> doesn't (and probably never will) allow <el>xforms:repeat</el> elements as children, another syntax is needed.</p> <example> <head>Tables And Repeating Structures</head> <eg xml:space="preserve"><table> <repeat nodeset="..."> <tr> <td>...</td> ... </tr> </repeat> </table></eg> </example> <p>More generally, there is a need to integrate repeat behavior into host languages at points where the content model of the host language does not or cannot provide the appropriate extension hooks via modularization. To accommodate this, XForms defines an alternative syntax that is functionally equivalent to the <el>repeat</el> element, using the following attributes: </p> <slist> <sitem> <code>repeat-model</code> </sitem> <sitem> <code>repeat-bind</code> </sitem> <sitem> <code>repeat-nodeset</code> </sitem> <sitem> <code>repeat-startindex</code> </sitem> <sitem> <code>repeat-number </code> </sitem> </slist> <p> The above attributes are equivalent to the <el>repeat</el> attributes of the same name, but without the prefix <code>repeat-</code>. A host language can include these attributes in the appropriate places to enable repeating constructs. For example, a version of XHTML might use:</p> <example> <head>Tables And Repeating Structures</head> <eg xml:space="preserve"><html:table xforms:repeat-nodeset="..."> <html:tr> <html:td><xforms:output ref="..."/></html:td> </html:tr> </html:table></eg> <p>Which could be validated against an appropriately configured XHTML Schema that includes the XForms Repeat module. Note that what gets repeated is the child elements of the element with the <code>repeat-</code> attributes.</p> </example> <p>Additionally, when using XForms Action <code>setindex</code>, attribute <att>repeat</att> of type <code>idref</code> can point to any element carrying the repeat attributes. Similarly, when using function <code>index</code> against a repeating structure created via the <code>repeat-</code>attributes, the <code>id</code> of that element can be used as the argument to function <code>index</code>.</p> </div3> <div3 id="ui-common-elements-itemset"> <head>The itemset Element</head> <p>This element allows the creation of dynamic selections within controls <el>select</el> and <el>select1</el>, where the available choices are determined at run-time. The node-set that holds the available choices is specified via the Node Set Binding. As with <el>repeat</el>, this nodeset should refer to a <termref def="defn-homogeneous">homogeneous</termref> collection. Child elements <el>label</el> and <el>value</el> indirectly specify the label and storage values. Notice that the run-time effect of <el>itemset</el> is the same as using element <el>choices</el> with child <el>item</el> elements to statically author the available choices.</p> <p>For each node of the Node Set Binding, an associated <el>item</el> is created. XForms Actions appearing in the content of an <el>itemset</el> are created within each <el>item</el> element, and the in-scope evaluation context for these XForms Actions is based on the node for which the <el>item</el> was generated as described in Section <specref ref="expr-eval"/>. An XForms processor must not allow XForms Actions contained by an <el>itemset</el> to handle events on the <el>itemset</el>.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="structure-attrs-nodeset">Node Set Binding</termref></p> <note> <p>Whenever a <code>refresh</code> event is dispatched the <code>nodeset</code> is re-evaluated to update the list of available choices.</p> </note> <p> The following example shows element <el>itemset</el> within control <el>select</el> to specify a dynamic list of ice cream flavors:</p> <example> <head>Dynamic Choice Of Ice Cream Flavors</head> <eg xml:space="preserve"><model id="cone"> <instance> <my:icecream> <my:order/> </my:icecream> </instance> </model> <model id="flavors"> <instance> <my:flavors> <my:flavor type="v"> <my:description>Vanilla</my:description> </my:flavor> <my:flavor type="s"> <my:description>Strawberry</my:description> </my:flavor> <my:flavor type="c"> <my:description>Chocolate</my:description> </my:flavor> </my:flavors> </instance> </model> <!-- user interaction markup --> <select model="cone" ref="my:order"> <label>Flavors</label> <itemset model="flavors" nodeset="/my:flavors/my:flavor"> <label ref="my:description"/> <copy ref="my:description"/> </itemset> </select> <!-- For all three items selected, this example produces instance data like <my:icecream> <my:order> <my:description>Vanilla</my:description> <my:description>Strawberry</my:description> <my:description>Chocolate</my:description> </my:order> </my:icecream> --></eg> </example> </div3> <div3 id="ui-adv-copy"> <head id="ui-copy">The copy Element</head> <p>Structurally, this element is similar to <specref ref="ui-common-choices-value"/>. It differs in that it can only be used within <el>itemset</el>, and that it works with subtrees of instance data rather than simple values.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="structure-attrs-single-node">Single Node Binding</termref> (optional)</p> <p>When an <el>item</el> becomes selected, the following rules apply:</p> <ulist> <item> <p>The target node, selected by the binding attributes on the list form control, must be an element node, otherwise an exception results (<specref ref="evt-bindingException"/>).</p> </item> <item> <p>The element node associated with the <el>item</el>, selected by the binding attributes on <el>copy</el>, is deep copied as a child of the target node.</p> </item> <item> <p>A full computational dependency rebuild is done.</p> </item> </ulist> <p>When an <el>item</el> becomes unselected, the following rules apply:</p> <ulist> <item> <p>The target node, selected by the binding attributes on the list form control, must be an element node, otherwise an exception results (<specref ref="evt-bindingException"/>).</p> </item> <item> <p>The child element node associated with the <el>item</el>, selected by the binding attributes on <el>copy</el>, is deleted.</p> </item> <item> <p>A full computational dependency rebuild.</p> </item> </ulist> </div3> <div3 id="action-insert"> <head>The <el>insert</el> Action</head> <p> The <el>insert</el> action is used to create one or more nodes of instance data by cloning one or more existing instance nodes. Attributes of the <el>insert</el> action specify the node or nodes to be cloned and the location within instance data where the clones will appear. The clones are deep copies of the original nodes except the contents of nodes of type <code>xsd:ID</code> are modified to remain as unique values in the instance data after the clones are inserted. </p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref>, <phrase diff="add"><termref def="attrs-action-common">Action Common</termref>,</phrase> <termref def="structure-attrs-nodeset">Node Set Binding</termref> (optional)</p> <p>Special Attributes:</p> <glist> <gitem> <label>context</label> <def> <p> <!--Optional XPath expression used to change the <code>insert context</code> used to override the--> <!--in-scope evaluation context node. This attribute is ignored if the <att>bind</att> attribute is--> <!--present. If this attribute is present, a Node Set Binding attribute is optional.--> Optional attribute containing an XPath expression evaluated using the in-scope evaluation context. If the <att>model</att> attribute is present, then it is processed as described in <specref ref="expr-eval"/> before evaluating this attribute. The Node Set Binding is required unless this attribute is present. This attribute is ignored if the <att>bind</att> attribute is present. Otherwise, the result of the XPath expression is used to override the in-scope evaluation context. If the result is an empty nodeset or not a nodeset, then the insert action is terminated with no effect. Otherwise, the first node of the nodeset is used as the new in-scope evaluation context node, and the context position and size are set to 1. By adjusting the in-scope evaluation context, this attribute affects the evaluation of subsequent attributes that may appear on <el>insert</el>, including <att>if</att>, <att>while</att>, <att>nodeset</att> and <att>origin</att>. </p> </def> </gitem> <gitem> <label>origin</label> <def> <p> <!--Optional XPath expression used to change the <code>origin node-set</code> containing the node or--> <!--nodes to be cloned.--> Optional attribute containing an XPath expression evaluated using the in-scope evaluation context. The <code>origin node-set</code> is the set of one or more nodes to be cloned by the <el>insert</el> action. If this attribute is present and resolves to a non-empty nodeset, then the result overrides the default setting of the <code>origin node-set</code> as described below in the processing of the <el>insert</el> action. </p> </def> </gitem> <gitem> <label>at</label> <def> <p> <!--Optional XPath expression evaluated to change the <code>insert location node</code> within the--> <!--Node Set Binding node-set. If the Node Set Binding node-set is not specified or empty, then this--> <!--attribute is ignored.--> Optional attribute containing an XPath expression evaluated using the in-scope evaluation context. This attribute is ignored if the Node Set Binding is not specified or specifies an empty node-set. The <code>insert location node</code> is a node within the Node Set Binding node-set that is used to help determine where in the instance to insert each node cloned by the <el>insert</el>. If this attribute is present, then its result is used to override the default setting of the <code>insert location node</code> as described below in the processing of the <el>insert</el> action. </p> </def> </gitem> <gitem> <label>position</label> <def> <p> Optional selector that indicates where to put the cloned node or nodes relative to the <code>insert location node</code>. Valid values are <code>before</code> and <code>after</code>, and the latter is the default. This attribute is ignored if the Node Set Binding node-set is not specified or empty. If the node at the <code>insert location node</code> within the Node Set Binding node-set is the document element of an instance, then this attribute is ignored. </p> </def> </gitem> </glist> <p> Processing for the <el>insert</el> action is as follows: </p> <olist> <!--<item>--> <!--<p>--> <!--If the <att>model</att> attribute is given and indicates a model different than the one containing the--> <!--in-scope evaluation context node, then the in-scope evaluation context is changed. The size and--> <!--position are changed to 1, and the node is changed to the document element node of the default instance--> <!--of the indicated model.--> <!--</p>--> <!--</item>--> <item> <p> The <code>insert context</code> is determined. If the <att>bind</att> attribute is present or if the <att>context</att> attribute is not given, the <code>insert context</code> is the in-scope evaluation context. Otherwise, the XPath expression provided by the <att>context</att> attribute is evaluated using the in-scope evaluation context, and the first node rule is applied to obtain the <code>insert context</code>. The <el>insert</el> action is terminated with no effect if the <code>insert context</code> is the empty node-set<phrase diff="del">, or if the <code>insert context</code> is not an element</phrase>. </p> </item> <item> <p> The Node Set Binding node-set is determined. If a <att>bind</att> attribute is present, it directly determines the Node Set Binding node-set. If a <att>nodeset</att> attribute is present, it is evaluated within the <code>insert context</code> to determine the Node Set Binding node-set. If the Node Set Binding attributes are not present, then the Node Set Binding node-set is the empty node-set. The <el>insert</el> action is terminated with no effect if any of the following conditions is true: </p> <olist> <item> <p> The <att>context</att> attribute is not given and the Node Set Binding node-set is the empty node-set. </p> </item> <item> <p> The <att>context</att> attribute is given, the <code>insert context</code> does not evaluate to an element node and the Node Set Binding node-set is the empty node-set. </p> </item> </olist> </item> <item> <p> The <code>origin node-set</code> is determined. If the <att>origin</att> attribute is not given and the Node Set Binding node-set is empty, then the <code>origin node-set</code> is the empty node-set. Otherwise, if the <att>origin</att> attribute is not given, then the <code>origin node-set</code> consists of the last node of the Node Set Binding node-set. If the <att>origin</att> attribute is given, the <code>origin node-set</code> is the result of the evaluation of the <att>origin</att> attribute in the <code>insert context</code>. The <el>insert</el> action is terminated with no effect if the <code>origin node-set</code> is the empty node-set. </p> </item> <item> <p> The <code>insert location node</code> is determined. If the Node Set Binding node-set is not specified or empty, the <code>insert location node</code> is the <code>insert context</code> node. Otherwise, if the <att>at</att> attribute is not given, then the <code>insert location node</code> is the last node of the Node Set Binding node-set. Otherwise, an <code>insert location node</code> is determined from the <att>at</att> attribute as follows: </p> <olist> <item> <p> The evaluation context node is the first node in document order from the Node Set Binding node-set, the context size is the size of the Node Set Binding node-set, and the context position is <code>1</code>. </p> </item> <item> <p> The return value is processed according to the rules of the XPath function <code>round()</code>. For example, the literal <code>1.5</code> becomes <code>2</code>, and the literal <code>'string'</code> becomes <code>NaN</code>. </p> </item> <item> <p> If the result is in the range 1 to the Node Set Binding node-set size, then the <code>insert location</code> is equal to the result. If the result is non-positive, then the <code>insert location</code> is <code>1</code>. Otherwise, the result is <code>NaN</code> or exceeds the Node Set Binding node-set size, so the <code>insert location</code> is the Node Set Binding node-set size. </p> </item> <item> <p> The <code>insert location node</code> is the node in the Node Set Binding node-set at the position given by the <code>insert location</code>. </p> </item> </olist> </item> <item> <p> Each node in the <code>origin node-set</code> is cloned in the order it appears in the <code>origin node-set</code>. </p> </item> <item> <p> The <code>target location</code> of each cloned node or nodes is determined as follows: </p> <olist> <item> <p> If the Node Set Binding node-set is not specified or empty, the <code>target location</code> depends on the node type of the cloned node. If the cloned node is an attribute, then the <code>target location</code> is <phrase diff="add">the attribute list of the parent element of </phrase> <phrase diff="del">before the first attribute of</phrase> the <code>insert location node</code>. If the cloned node is not an attribute, then the <code>target location</code> is before the first child of the <code>insert location node</code>. </p> </item> <item diff="del"> <p> Otherwise, if the Node Set Binding node-set is specified and not empty and the type of the cloned node is different from the type of the <code>insert location node</code>, the <code>target location</code> depends on the node type of the cloned node. If the cloned node is an attribute, then the <code>target location</code> is <phrase diff="add">the attribute list of the parent element of </phrase> <phrase diff="del">before the first attribute of</phrase> the <code>insert location node</code> node. If the cloned node is not an attribute, then the <code>target location</code> is before the first child of the <code>insert location node</code>. </p> </item> <item> <p> Otherwise, if <code>insert location node</code> is the root element of an instance, then that instance root element location is the <code>target location</code>. If there is more than one cloned node to insert, only the first node that does not cause a conflict is considered. </p> </item> <item> <p> Otherwise, the <code>target location</code> is immediately before or after the <code>insert location node</code>, based on the <att>position</att> attribute setting or its default. </p> </item> </olist> </item> <item> <p> The cloned node or nodes are inserted in the order they were cloned at their <code>target location</code> depending on their node type. If the <code>target location</code> was the root element of an instance, then the cloned node replaces the instance root element. If the cloned node is a duplicate of another attribute in its parent element, then the duplicate attribute is first removed. If a cloned node cannot be placed at the <code>target location</code> due to a node type conflict, then the insertion for that particular clone node is ignored. </p> </item> <item> <p> The index for any <el>repeat</el> that is bound to a homogeneous collection where <phrase diff="del">the cloned node was</phrase><phrase diff="add">one or more nodes were</phrase> added is updated to point to the <phrase diff="del">newly inserted node</phrase><phrase diff="add">last node inserted into the collection</phrase>, and the index of any <el>repeat</el> nested within an updated <el>repeat</el> is re-initialized to the <att>startindex</att> of the nested <el>repeat</el>. If the <att>startindex</att> is less than 1 the index is set to 1. If the <att>startindex</att> is greater than the size of the homogeneous collection, then the index is set to the size of the homogeneous collection. </p> </item> <item><p>The XForms action system's deferred update flags for rebuild, recalculate, revalidate and refresh are set.</p></item> <item> <p> The <el>insert</el> action is successfully completed by dispatching the <code>xforms-insert</code> event with appropriate context information. </p> </item> </olist> <note diff="add"> <p> This action affects <termref def="action-deferred-update">deferred update behavior</termref>.</p> </note> <example> <head>Inserting the clone of a prototypical element (append child, prepend child)</head> <eg> ... <xforms:instance id="people"> <people xmlns=""/> </xforms:instance> <xforms:instance id="personProto"> <person xmlns=""> <name>Jane Q. Public</name> </person> </xforms:instance> ... <xforms:trigger> <xforms:label>Append new person</xforms:label> <xforms:insert context="instance('people')" nodeset="person" origin="instance('personProto')" ev:event="DOMActivate"/> </xforms:trigger> <xforms:trigger> <xforms:label>Prepend new person</xforms:label> <xforms:insert context="instance('people')" nodeset="person" origin="instance('personProto')" at="1" position="before" ev:event="DOMActivate"/> </xforms:trigger> ... </eg> <note><p>Generalized append/prepend child can be done with <code>nodeset="*"</code> for elements and <code>nodeset="@*"</code> for attributes. </p></note> </example> <example> <head>Replacing an instance</head> <eg> ... <xforms:instance id="people"> <people xmlns=""> <person> <name>Jane Q. Public</name> </person> <person> <name>John Hancock</name> </person> </people> </xforms:instance> ... <xforms:instance id="peopleProto"> <people xmlns=""/> </xforms:instance> ... <trigger> <label>Clear Person List</label> <insert context="instance('people')" nodeset="." origin="instance('peopleProto')" ev:event="DOMActivate"/> </trigger> ... </eg> </example> <example> <head>Duplicating a node</head> <eg> <insert nodeset="some/node"/> </eg> </example> <example> <head>Copying an attribute</head> <eg> <xforms:instance xmlns=""> <data> <item show="true">...</item> <item>...</item> <item willbesecondattr="true" show="false">...</item> <item willbesecondattr="false" show="false">...</item> </data> </xforms:instance> ... <insert nodeset="item[2]" origin="item[1]/@show"/> <insert nodeset="item[3]" origin="item[1]/@show"/> <insert nodeset="item[4]/@show" origin="item[1]/@show"/> ... </eg> <p>After the <el>insert</el> actions, all <el>item</el> elements have attribute <code>show="true"</code>, and it will be the first attribute except for the last <el>item</el>. The existing <att>show</att> attribute is removed from the third and fourth <el>item</el>, but in the third <el>item</el> the location of the new attribute is at the beginning due to node type mismatch, and in the fourth <el>item</el> the location of the new attribute after (due to position default) the existing <att>show</att> attribute.</p> </example> <example> <head>Inserting into a <el>repeat</el>, whether or not it is empty</head> <p>When the <el>repeat</el> is empty, the <att>at</att> index is zero so a new <el>item</el> is prepended. When the <el>repeat</el> is non-empty, the new <el>item</el> is added after the node currently indexed by repeat <code>R</code>.</p> <eg> ... <xforms:instance xmlns=""> <purchaseOrder> <subtotal/> <tax/> <total/> </purchaseOrder> </xforms:instance> <xforms:instance xmlns="" id="prototypes"> <prototypes> ... <item> <product/> <quantity/> <unitcost/> <price/> </item> </prototypes> </xforms:instance> ... <repeat nodeset="/purchaseOrder/item" id="R"> ... </repeat> ... <xforms:trigger> <xforms:label>Add to purchase order</xforms:label> <xforms:action ev:event="DOMActivate> <xforms:insert context="/purchaseOrder" nodeset="item" at="index('R')" origin="instance('prototypes')/item"/> <xforms:setfocus control="R"/> </xforms:action> </xforms:trigger> </eg> </example> <example> <head>Copying several nodes from one location to the other</head> <eg> ... <xforms:instance xmlns="" id="destination"> <items/> </xforms:instance> <xforms:instance xmlns="" id="source"> <items> <item> <product/> <quantity/> <unitcost/> <price/> </item> <item> <product/> <quantity/> <unitcost/> <price/> </item> </items> </xforms:instance> ... <xforms:trigger> <xforms:label>Copy items</xforms:label> <xforms:insert ev:event="DOMActivate context="instance('destination')" origin="instance('source')/item"/> </xforms:trigger> </eg> </example> </div3> <div3 id="action-delete"> <head>The <el>delete</el> Action</head> <p>This action deletes one or more nodes from instance data.</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref>, <phrase diff="add"><termref def="attrs-action-common">Action Common</termref>,</phrase> <termref def="structure-attrs-nodeset">Node Set Binding</termref></p> <!--<p>--> <!--If the <att>bind</att> attribute is present, then the delete context is the in-scope evaluation context.If the--> <!--<att>model</att> attribute is given and indicates a model different than the one containing the in-scope--> <!--evaluation context node, then the in-scope evaluation context is changed prior to evaluation of the Special--> <!--Attributes of the <el>delete</el> element. The size and position are changed to 1, and the node is changed to--> <!--the document element node of the default instance of the indicated mode.--> <!--</p>--> <p>Special Attributes:</p> <glist> <gitem> <label>context</label> <def> <p> <!--Optional XPath expression used to change the in-scope evaluation context for the <el>delete</el>--> <!--element. This attribute is ignored if the <att>bind</att> attribute is provided. If the attribute--> <!--is not given, then the default <code>delete context</code> is the in-scope evaluation context.--> <!--Otherwise, the XPath expression is evaluated using the in-scope evaluation context, and the first--> <!--node rule is applied to obtain the <code>delete context</code>. The <el>delete</el> action is--> <!--terminated with no effect if the <code>delete context</code> is the empty node-set or if the--> <!--<att>context</att> attribute is not given and the Node Set Binding node-set is not specified or--> <!--empty.--> Optional attribute containing an XPath expression evaluated using the in-scope evaluation context. If the <att>model</att> attribute is present, then it is processed as described in <specref ref="expr-eval"/> before evaluating this attribute. This attribute is ignored if the <att>bind</att> attribute is present. Otherwise, the result of the XPath expression is used to override the in-scope evaluation context. If the result is an empty nodeset or not a nodeset, then the <code>delete</code> action is terminated with no effect. Otherwise, the first node of the nodeset is used as the new in-scope evaluation context node, and the context position and size are set to 1. By adjusting the in-scope evaluation context, this attribute affects the evaluation of subsequent attributes that may appear on <el>delete</el>, including <att>if</att>, <att>while</att>, and <att>nodeset</att>. </p> </def> </gitem> <gitem> <label>at</label> <def> <p> Optional attribute containing an XPath expression evaluated using the Node Set Binding node-set to determine the <code>delete location</code>. If the Node Set Binding node-set is empty, then this attribute is ignored. </p> </def> </gitem> </glist> <p> <!--Provided the delete action has not been terminated due to the conditions stated above, the rules for--> <!--<el>delete</el> processing are as follows:--> Processing for the <code>delete</code> action is as follows: </p> <olist> <item> <p> The <code>delete context</code> is determined. It is set to the in-scope evaluation context, possibly overridden by the <att>context</att> attribute if that attribute is present. The <el>delete</el> action is terminated with no effect if the <code>delete context</code> is the empty node-set. </p> </item> <item> <p> The Node Set Binding node-set is determined. If a <att>bind</att> attribute is present, it directly determines the Node Set Binding node-set. If a <att>nodeset</att> attribute is present, it is evaluated within the <code>delete context</code> to determine the Node Set Binding node-set. <!-- If the Node Set Binding attributes are not present, then the Node Set Binding node-set is the empty node-set. --> The <el>delete</el> action is terminated with no effect if Node Set Binding node-set is the empty node-set. </p> </item> <item> <p> The <code>delete location</code> is determined. If the <att>at</att> attribute is not specified, there is no <code>delete location</code>. Otherwise, the <code>delete location</code> is determined by evaluating the XPath expression specified by the <att>at</att> attribute as follows: </p> <olist> <item><p> The evaluation context node is the first node in document order from the Node Set Binding node-set, the context size is the size of the Node Set Binding node-set, and the context position is <code>1</code>. </p></item> <item><p> The return value is processed according to the rules of the XPath function <code>round()</code>. For example, the literal <code>1.5</code> becomes <code>2</code>, and the literal <code>'string'</code> becomes <code>NaN</code>. </p></item> <item><p> If the result is in the range 1 to the Node Set Binding node-set size, then the <code>delete location</code> is equal to the result. If the result is non-positive, then the <code>delete location</code> is <code>1</code>. Otherwise, if the result is <code>NaN</code> or exceeds the Node Set Binding node-set size, the <code>delete location</code> is the Node Set Binding node-set size. </p></item> </olist> </item> <item> <p> If there is no <code>delete location</code>, each node in the Node Set Binding node-set is deleted, except if the node is the root document element of an instance then that particular node is not deleted. Otherwise, if there is a <code>delete location</code>, the node at the <code>delete location</code> in the Node Set Binding node-set is deleted, except if the node is the root document element of an instance then that node is not deleted. The delete action is terminated with no effect if no node is deleted. </p> </item> <item> <p> The index for any <el>repeat</el> that is bound to a homogeneous collection that contained one of the deleted nodes is adjusted as follows: </p> <olist> <item><p> If, prior to node deletion, the index pointed to a node that is still contained in the collection after node deletion, the index is adjusted, if necessary, to point to that same node. If the index is changed, the indexes of inner repeats are reinitialized. </p></item> <item><p> Otherwise, when the last remaining node in the collection is removed, the index position becomes 0 and the indexes of inner repeats become 0 as well. </p></item> <item><p> Otherwise, when the index was pointing to one of the deleted nodes, and if the new size of the collection is smaller than the index, the index is changed to the new size of the collection and the indexes of inner repeats are reinitialized. </p></item> <item><p> Otherwise, when the index was pointing to one of the deleted nodes, and if the new size of the collection is equal to or greater than the index, the index is not changed but the indexes of inner repeats are reinitialized. </p></item> </olist> <p> To re-initialize a repeat index means to change its value to be equal to <att>startindex</att>, or to the size of the homogeneous collection if it contains less than <att>startindex</att> items. </p> </item> <item> <p> The XForms action system's deferred update flags for rebuild, recalculate, revalidate and refresh are set. </p> </item> <item> <p> The <el>delete</el> action is successfully completed by dispatching the <code>xforms-delete</code> event with appropriate context information. </p> </item> </olist> <note diff="add"> <p> This action affects <termref def="action-deferred-update">deferred update behavior</termref>.</p> </note> <example> <head>Deleting from a <el>repeat</el></head> <p>In this example, the <el>trigger</el> is not in the <el>repeat</el>. When it is activated, the indexed <el>item</el> in the repeat is first deleted. Next, if that was the last <el>item</el>, then a new prototypical <el>item</el> is inserted so that the <el>repeat</el> does not become empty. The focus is then sent back to the <el>repeat</el> from the <el>trigger</el>.</p> <eg> ... <xforms:trigger> <xforms:label>Delete from purchase order</xforms:label> <xforms:action ev:event="DOMActivate"> <xforms:delete context="/purchaseOrder" nodeset="item" at="index('R')"/> <xforms:insert context="/purchaseOrder" if="not(item)" nodeset="item" origin="instance('prototypes')/item"/> <xforms:setfocus control="R"/> </xforms:action> </xforms:trigger> </eg> <note><p>The form author could have written <code>nodeset="/purchaseOrder/item"</code> in the <el>delete</el> action, but the <att>context</att> attribute was added for consistency with the <el>insert</el> action.</p></note> </example> <example> <head>Deleting several instance nodes</head> <p> In this example, when the <el>trigger</el> is activated, all the <el>item</el> elements under the <code>shopping-cart</code> instance are deleted. </p> <eg> ... <xforms:trigger> <xforms:label>Empty shopping cart</xforms:label> <xforms:delete ev:event="DOMActivate" context="instance('shopping-cart')" nodeset="item"/> </xforms:trigger> </eg> </example> </div3> <div3 id="action-setindex"> <head>The setindex Element</head> <p> This action marks a specific item as current in a repeating sequence (within <specref ref="ui-repeat"/>).</p> <p>Common Attributes: <termref def="structure-attrs-common">Common</termref>, <termref def="action-xmlevents">Events</termref><phrase diff="add">, <termref def="attrs-action-common">Action Common</termref></phrase> </p> <p>Special Attributes:</p> <glist> <gitem> <label>repeat</label> <def> <p>Required reference to a repeating element.</p> </def> </gitem> <gitem> <label>index</label> <def> <p>Required XPath expression that evaluates to a 1-based offset into the sequence. The evaluation context is determined in the same manner as the evaluation context for a Single-Node Binding (see <specref ref="expr-eval"/>).</p> </def> </gitem> </glist> <p>If the selected index is 0 or less, an <code>xforms-scroll-first</code> event is dispatched and the index is set to 1. If the selected index is greater than the index of the last repeat item, an <code>xforms-scroll-last</code> event is dispatched and the index is set to that of the last item. If the index evaluates to NaN the action has no effect. The indexes for inner nested repeat collections are re-initialized to <att>startindex</att>. The implementation data structures for tracking computational dependencies are rebuilt or updated as a result of this action.</p> <note> <p>The IDREF from the <att>repeat</att> attribute may not uniquely identify the desired <termref def="ui-repeat">repeat</termref> if the <el>repeat</el> element bearing the matching ID resides within the content of another <el>repeat</el>. The general method described in <specref ref="idref-resolve"/> is used to determine the desired run-time repeat object.</p> </note> </div3> <div3 id="ui-repeat-processing"> <head>Repeat Processing</head> <p> The markup contained within the body of element <el>repeat</el> specifies the user interface to be generated for each member of the underlying collection. During user interface initialization (see <specref ref="evt-modelConstructDone"/>), the following steps are performed for <el>repeat</el>:</p> <olist> <item> <p>The Node Set Binding is evaluated to locate the homogeneous collection to be operated on by this <el>repeat</el>.</p> </item> <item> <p> The <emph>index</emph> for this repeating structure is initialized to the value of <att>startindex</att>. If the initial <el>startindex</el> is less than 1 it defaults to 1. If the index is greater than the initial node-set then it defaults to the size of the node-set.</p> </item> <item> <p> User interface as specified by the <el>repeat</el> is generated for the requisite number of members of the collection as specified by attributes on element <el>repeat</el>. </p> </item> </olist> <p> The processing model for repeating structures uses an <emph>index</emph> that points to the <emph>current</emph> item in the instance data. This repeat index is accessed via XForms function <function>index</function> <specref ref="fn-index"/> and manipulated via XForms Action <el>setindex</el> <specref ref="action-setindex"/>. This index is used as a reference point for <code>insert</code> and <code>delete</code> operations. Notice that the contained XForms form controls inside element <el>repeat</el> do not explicitly specify the index of the collection entry being populated. This is intentional; it keeps both authoring as well as the processing model simple.</p> <p> The binding expression attached to the repeating sequence returns a node-set of the collection being populated, not an individual node. Within the body of element <el>repeat</el>, binding expressions are evaluated with a context node of the node determined by the index. Repeat processing uses XPath expressions to address the collection over which element <el>repeat</el> operates. </p> <p> The form controls appearing inside <el>repeat</el> need to be suitable for populating individual items of the collection. A simple but powerful consequence of the above is that if the XForms Model specifies nested collections, then a corresponding user interface can nest <el>repeat</el> elements. </p> </div3> <div3 id="ui-nested-repeats"> <head>Nested Repeats</head> <p> It is possible to nest repeat elements to create more powerful user interface for editing structured data. <specref ref="bookmarks-in-x-smiles"/> is an example of a form using nested repeats to edit hierarchical data consisting of bookmarks within multiple sections. Consider the following <code>insert</code> statement that appears as part of that example. </p> <example> <head>Repeat Index and Nested Repeats</head> <eg xml:space="preserve"><xforms:insert nodeset="/bookmarks/section[index('repeatSections')]/bookmark" at="index('repeatBookmarks')" position="after"/></eg> </example> <p> The above <code>insert</code> statement is used in that example to add new bookmark entries into the <emph>currently selected</emph> section. The inner (nested) repeat operates on bookmarks in this selected section; The indexâ??as returned by XForms function <function>index</function>â??for this inner repeat starts at <code>1</code>. Hence, after a new empty section of bookmarks is created and becomes <emph>current</emph>, the first <emph>insert bookmark</emph> operation adds the newly created bookmark at the front of the list.</p> </div3> <div3 id="ui-repeat-ui"> <head>User Interface Interaction</head> <p> Element <el>repeat</el> enables the binding of user interaction to a homogeneous collection. The number of displayed items might be less than the total number available in the collection. In this case, the presentation would render only a portion of the repeating items at a given time. For example, a graphical user interface might present a scrolling table. The current item indicated by the repeat index should be made available to the user at all times, for example, not allowed to scroll out of view. The XForms Actions enumerated at <specref ref="action"/> may be used within event listeners to manipulate the homogeneous collection being populated by scrolling, inserting, and deleting entries. </p> <p>Notice that the markup encapsulated by element <el>repeat</el> acts as the template for the user interface that is presented to the user. As a consequence, statically authored <code>IDREF</code> attributes must be interpreted based on a combination of repeat indexes and where the IDREF attributes appear relative to the element bearing the matching ID. Based on the IDREF resolution rules given in <specref ref="idref-resolve"/>, it is possible to toggle the <el>case</el> of a <el>switch</el> even when it is within one or more <el>repeat</el> elements. Similarly, it is possible to set the focus to controls and dispatch events to elements that are within one or more <el>repeat</el> elements.</p> <p>If the focus is transferred to a control within a <el>repeat</el> by any means, such as by an XForms action or by user interaction, the index of the <el>repeat</el> is changed to indicate the item of the homogeneous collection that contains the control. This effect is recursive; the index of each containing <el>repeat</el> is adjusted appropriately.</p> </div3> </div2> </div1>
Received on Tuesday, 24 July 2007 00:25:00 UTC