Reputation: 1699
I have a form that is using repeatable sections. This works fine when using relative path to the nodes of the form. The problem is that I want to not force to have unique names in the nodes of the form. An example:
<form>
<section-personalData>
<age/>
</section-personalData>
<section-kids-personalData>
<section-kids-personalData-iterator>
<age/>
</section-kids-personalData-iterator>
</section-kids-personalData>
</form>
In this example, as element <age>
is in a different level, is allowed to have the same name. Of course, for allowing it, when defining the <bind>
part of the node, I need to specify the complete path of the node to avoid confusion.
<xf:bind id="age-bind" name="age" ref="/form/section-personalData/age" required="true()"/>
This is working correctly. The problem comes with the element that is inside the repeatable section.
<xf:bind id="age-1-bind" name="age-1" ref="/form/section-kids-personalData/section-kids-personalData-iterator/age" required="true()"/>
This almost work but I have found an unexpected behaviour. When you have more than one iteration and answer the age
value, all iterations ALWAYS have the same answer (when you change one of them, ALL are changed). I have experimented this with Input Fields, Radio Buttons, ...
When using the Orbeon Builder, all elements must have a unique name. But we are interested in have the same name in both elements due to client restrictions.
I copy a complete example that can be executed in Orbeon to test the problem.
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude">
<xh:head>
<xh:meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<xh:title>Loop</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>WebForms</application-name>
<form-name>Loop_v1</form-name>
<title xml:lang="en">Loop</title>
<description xml:lang="en">Version: 1. Modification date: 2014-12-04 10:06:03. Publication date: 2014-12-04 10:52:43.</description>
</metadata>
</xf:instance>
<xf:instance id="fr-form-instance">
<form>
<Category1>
<Loop>
<Loop-iterator>
<Question/>
</Loop-iterator>
</Loop>
</Category1>
</form>
</xf:instance>
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="Category1-bind" name="Category1" ref="/form/Category1">
<xf:bind id="Loop-bind" name="Loop" ref="/form/Category1/Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="/form/Category1/Loop/Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="/form/Category1/Loop/Loop-iterator/Question"
required="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
</xf:bind>
<xf:instance id="fr-form-attachments">
<attachments>
<css filename="" mediatype="text/css" size=""/>
<pdf filename="" mediatype="application/pdf" size=""/>
</attachments>
</xf:instance>
<xf:instance id="fr-form-resources" xxf:readonly="false">
<resources>
<resource xml:lang="en">
<Category1>
<label>Category1</label>
<hint/>
<alert/>
<Loop>
<label>Loop</label>
<hint/>
<alert/>
<Question>
<label>Question</label>
<hint/>
<alert/>
<item>
<label>Answer</label>
<hint/>
<value>Answer</value>
</item>
<item>
<label>Answer2</label>
<hint/>
<value>Answer2</value>
</item>
<item>
<label>Answer3</label>
<hint/>
<value>Answer3</value>
</item>
</Question>
</Loop>
</Category1>
</resource>
</resources>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
<xf:instance xxf:readonly="true" id="Loop-template">
<Loop-iterator>
<Question/>
</Loop-iterator>
</xf:instance>
</xf:model>
</xh:head>
<xh:body>
<fr:view>
<fr:body xmlns:xbl="http://www.w3.org/ns/xbl"
xmlns:oxf="http://www.orbeon.com/oxf/processors"
xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:dataModel="java:org.orbeon.oxf.fb.DataModel">
<fr:section bind="Category1-bind" id="Category1-control">
<xf:label mediatype="text/html" ref="$form-resources/Category1/label"/>
<xf:hint ref="$form-resources/Category1/hint"/>
<xf:alert ref="$form-resources/Category1/alert"/>
<fr:section bind="Loop-bind" id="Loop-control" max="100" min="1" repeat="true"
template="instance('Loop-template')">
<xf:label mediatype="text/html" ref="$form-resources/Category1/Loop/label"/>
<xf:hint ref="$form-resources/Category1/Loop/hint"/>
<xf:alert ref="$form-resources/Category1/Loop/alert"/>
<xh:tr>
<xh:td>
<xf:select1 appearance="full" bind="Question-bind" id="Question-control">
<xf:label mediatype="text/html" ref="$form-resources/Category1/Loop/Question/label"/>
<xf:hint ref="$form-resources/Category1/Loop/Question/hint"/>
<xf:alert ref="$form-resources/Category1/Loop/Question/alert"/>
<xf:itemset ref="$form-resources/Category1/Loop/Question/item">
<xf:label ref="label"/>
<xf:value ref="value"/>
<xf:hint ref="hint"/>
</xf:itemset>
</xf:select1>
</xh:td>
</xh:tr>
</fr:section>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
</xh:html>
In this example it is impossible to have different values for any repeated value of Question.
I really need to have the same name for both nodes, then I think that using a complete xpath is the solution. Therefore question is: how I can use a complete path for an element that is inside of a repeatable section? For any other case the complete xpath works correctly. (I am using Orbeon 4.7 at this moment).
Upvotes: 0
Views: 195
Reputation: 7857
I should start by saying that changing the data format to support the same name in multiple places is asking for trouble. Things will break in Form Builder if you do that, as it is currently a strong assumption. And things might break in Form Runner as well.
This said, for repeats, you have to use relative XPath expressions. I do not see a way around it. So instead of:
<xf:bind id="Category1-bind" name="Category1" ref="/form/Category1">
<xf:bind id="Loop-bind" name="Loop" ref="/form/Category1/Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="/form/Category1/Loop/Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="/form/Category1/Loop/Loop-iterator/Question"
required="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
Use:
<xf:bind id="Category1-bind" name="Category1" ref="Category1">
<xf:bind id="Loop-bind" name="Loop" ref="Loop">
<xf:bind id="Loop-iterator-bind" name="Loop-iterator"
ref="Loop-iterator">
<xf:bind id="Question-bind" name="Question"
ref="Question"
required="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
It doesn't follow that, by using the same name in different places, you need to use absolute paths. The binds can be referred to with variables, and can be relative too. You should have a hierarchical structure like this:
<xf:bind id="section-personalData-bind" name="section-personalData">
<xf:bind id="age-bind" name="age" ref="age" required="true()"/>
</xf:bind>
<xf:bind id="section-kids-personalData-bind" name="section-kids-personalData">
<xf:bind id="section-kids-personalData-iteration-bind" name="section-kids-personalData-iterator">
<xf:bind id="age-1-bind" name="age-1" ref="age" required="true()"/>
</xf:bind>
</xf:bind>
Referring to $age
will find the first one, referring to $age-1
the second one.
Upvotes: 1