I am using a webservice through an action in a field to retrieve some aditional data as well as validate the user input. The validation is done by storing in a instance the validation status and make the input field to check that the code is not present to be valid. This works correctly as long as I don't try to use a repeated grid. When a repeated grid is used the same instance is used for all the repeated fields. The webservice data is loaded correctly independendtly, but the validation is shared between all of them. How can I adjust the code to work properly in repeated grids?
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:saxon="http://saxon.sf.net/"
xmlns:sql="http://orbeon.org/oxf/xml/sql"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
<xh:head>
<xh:title>repeated_ws</xh:title>
<xf:model id="fr-form-model" xxf:expose-xpath-types="true">
<!-- Main instance -->
<xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all">
<form>
<section-1>
<grid-4>
<grid-4-iteration>
<userId/>
<name/>
<address/>
</grid-4-iteration>
</grid-4>
</section-1>
</form>
</xf:instance>
<xf:instance id="repeatable-uid-instance">
<valid/>
</xf:instance>
<!-- Bindings -->
<xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
<xf:bind id="section-1-bind" name="section-1" ref="section-1">
<xf:bind id="grid-4-bind" ref="grid-4" name="grid-4">
<xf:bind id="grid-4-iteration-bind" ref="grid-4-iteration" name="grid-4-iteration">
<xf:bind id="userId-bind" ref="userId" name="userId">
<xf:constraint id="validation-9-validation"
value="instance('repeatable-uid-instance')/valid != 'not exist'"/>
</xf:bind>
<xf:bind id="name-bind" ref="name" name="name" readonly="true()"/>
<xf:bind id="address-bind" ref="address" name="address" readonly="true()"/>
</xf:bind>
</xf:bind>
</xf:bind>
</xf:bind>
<!-- Metadata -->
<xf:instance xxf:readonly="true" id="fr-form-metadata" xxf:exclude-result-prefixes="#all">
<metadata>
<application-name>test</application-name>
<form-name>repeated_ws</form-name>
<title xml:lang="en">repeated_ws</title>
<description xml:lang="en"/>
<singleton>false</singleton>
</metadata>
</xf:instance>
<!-- Attachments -->
<xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
<attachments>
<css mediatype="text/css" filename="" size=""/>
<pdf mediatype="application/pdf" filename="" size=""/>
</attachments>
</xf:instance>
<!-- All form resources -->
<!-- Don't make readonly by default in case a service modifies the resources -->
<xf:instance id="fr-form-resources" xxf:readonly="false" xxf:exclude-result-prefixes="#all">
<resources>
<resource xml:lang="en">
<userId>
<label>userId</label>
<hint/>
<alert>custom error</alert>
</userId>
<name>
<label>name</label>
<hint/>
</name>
<address>
<label>address</label>
<hint/>
</address>
<section-1>
<label>Untitled Section</label>
</section-1>
</resource>
</resources>
</xf:instance>
<!-- Utility instances for services -->
<xf:instance id="fr-service-request-instance" xxf:exclude-result-prefixes="#all">
<request/>
</xf:instance>
<xf:instance id="fr-service-response-instance" xxf:exclude-result-prefixes="#all">
<response/>
</xf:instance>
<xf:instance xxf:readonly="true" id="grid-4-template">
<grid-4-iteration>
<userId/>
<name/>
<address/>
</grid-4-iteration>
</xf:instance>
<xf:instance id="get-user-data-instance" class="fr-service"
xxf:exclude-result-prefixes="#all">
<body xmlns:secure="java:org.orbeon.oxf.util.SecureUtils"
xmlns:frf="java:org.orbeon.oxf.fr.FormRunner"
xmlns:p="http://www.orbeon.com/oxf/pipeline"
xmlns:fbf="java:org.orbeon.oxf.fb.FormBuilder"><bsn/></body>
</xf:instance>
<xf:submission id="get-user-data-submission" class="fr-service"
ref="instance('fr-service-request-instance')"
resource="http://localhost:8082/rest/getUserData"
method="post"
serialization="application/xml"
mediatype="application/xml"
replace="instance"
instance="fr-service-response-instance"/>
<xf:action id="call-get-user-data-binding">
<!-- React to event... on control... -->
<xf:action ev:event="xforms-value-changed xforms-enabled" ev:observer="userId-control"
if="true()">
<!-- Service to call -->
<xf:send submission="get-user-data-submission"/>
</xf:action>
<!-- Request actions -->
<xf:action ev:event="xforms-submit" ev:observer="get-user-data-submission">
<!-- Get reference to initial request -->
<xf:var name="request-instance-name" value="'get-user-data-instance'" as="xs:string"/>
<!-- Copy over to read-write request instance -->
<xf:insert ref="instance('fr-service-request-instance')"
origin="saxon:parse(instance($request-instance-name))"/>
<!--<xf:insert ref="instance('fr-service-request-instance')" origin="instance($request-instance-name)"/>-->
<!-- Set values if needed -->
<xf:action context="instance('fr-service-request-instance')">
<xf:action class="fr-set-service-value-action">
<xf:var name="control-name" value="'userId'"/>
<xf:var name="path" value="/bsn"/>
</xf:action>
<!-- Setvalue actions will be here -->
</xf:action>
</xf:action>
<!-- Response actions -->
<xf:action ev:event="xforms-submit-done" ev:observer="get-user-data-submission"
context="instance('fr-service-response-instance')">
<xf:action class="fr-set-control-value-action">
<xf:var name="control-name" value="'name'"/>
<xf:var name="control-value" value="/data/name"/>
</xf:action>
<xf:action class="fr-set-control-value-action">
<xf:var name="control-name" value="'address'"/>
<xf:var name="control-value" value="/data/address"/>
</xf:action>
<xf:insert origin="instance('fr-service-response-instance')"
ref="instance('repeatable-uid-instance')"/>
<!-- Response actions will be here -->
</xf:action>
</xf:action>
</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">
<fr:section id="section-1-control" bind="section-1-bind">
<xf:label ref="$form-resources/section-1/label"/>
<fr:grid id="grid-4-grid" bind="grid-4-bind" repeat="content" min="1"
template="instance('grid-4-template')">
<xh:tr>
<xh:td>
<xf:input id="userId-control" bind="userId-bind">
<xf:label ref="$form-resources/userId/label"/>
<xf:hint ref="$form-resources/userId/hint"/>
<xf:alert ref="$form-resources/userId/alert" validation="validation-9-validation"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr>
<xh:td>
<xf:input id="name-control" bind="name-bind">
<xf:label ref="$form-resources/name/label"/>
<xf:hint ref="$form-resources/name/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
<xh:tr>
<xh:td>
<xf:input id="address-control" bind="address-bind">
<xf:label ref="$form-resources/address/label"/>
<xf:hint ref="$form-resources/address/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
</xf:input>
</xh:td>
</xh:tr>
</fr:grid>
</fr:section>
</fr:body>
</fr:view>
</xh:body>
What version of Orbeon Forms are you using? Since 4.5, control resolution follows repeats in actions, so the result from your service should only change the
name
andaddress
of the current iteration, i.e. the one in which theuserId
changed and triggered the action to run, which seems to be what you are looking for.