Thomas Tsouskos
Thomas Tsouskos

Reputation: 11

Orbeon Form with repeated grid : Identify field values of same iteration

I am using Form Builder (version 4.9) to create a form containing a Repeated Grid. I've also defined a Process button, in order to send the form's data to a Servlet (using the send() method). My goal is to save the form data in a DB table.

I am able to receive the Form's data as XML in the servlet, but I noticed that a field having the same value in different iterations, appears only once per value in the XML, having a 'for' attribute with multiple values (indicating the number of the value repetitions). However, I haven't been able to find a way to match all fields of the same iteration (indicating one table row), so I am not able to store the data in the DB correctly.

For Example , when I post the following table

HEADERS :   FIELD_B     -  FIELD_C      -
ITER_1  :   FIELD_B_1   -  FIELD_C_1    -
ITER_2  :   FIELD_B_2   -  FIELD_C_2    -
ITER_2  :   FIELD_B_3   -  FIELD_C_1    -

I get the following XML

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
    <control for="e7d2bb4ac261e77159fc236e7fd922c3540756f8" name="section-1"
        type="section">
        <resources lang="en">
            <label>Untitled Section</label>
        </resources>
    </control>
    <control for="69ec5abdeb2df55c97bf5b1db46cce6bc841aed8" name="FIELD_A"
        type="input">
        <resources lang="en">
            <label>FIELD_A</label>
            <hint />
        </resources>
        <value>FIELD_A_V</value>
    </control>
    <control for="9749b7620379db1e8f86eeceaf52c60fa19484d2" name="FIELD_B"
        type="input">
        <resources lang="en">
            <label>FIELD_B</label>
            <hint />
        </resources>
        <value>FIELD_B_1</value>
    </control>
    <control
        for="89761405fd9de1a147bdda4d2c9279062b806016 9fa491ba6b72e86919e8a02226e28572c7309311"
        name="FIELD_C" type="input">
        <resources lang="en">
            <label>FIELD_C</label>
            <hint />
        </resources>
        <value>FIELD_C_1</value>
    </control>
    <control for="9cf502968950de2af58236fe0aaaab2a4fa5ac6d" name="FIELD_B"
        type="input">
        <resources lang="en">
            <label>FIELD_B</label>
            <hint />
        </resources>
        <value>FIELD_B_2</value>
    </control>
    <control for="46337304c26fca5cf9d5e91cdf393e3d39c0fbde" name="FIELD_C"
        type="input">
        <resources lang="en">
            <label>FIELD_C</label>
            <hint />
        </resources>
        <value>FIELD_C_2</value>
    </control>
    <control for="1155463007588b06b3842c534ca678aa6f5cf665" name="FIELD_B"
        type="input">
        <resources lang="en">
            <label>FIELD_B</label>
            <hint />
        </resources>
        <value>FIELD_B_3</value>
    </control>
</metadata>

As you can see, in iterations 1 and 3, FIELD_C contains the value FIELD_C_1. When parsing the XML, I am not able to find the order of the values of that field. I end up with the incorrect table :

HEADERS :   FIELD_B     -  FIELD_C      -
ITER_1  :   FIELD_B_1   -  FIELD_C_1    -
ITER_2  :   FIELD_B_2   -  FIELD_C_1    -
ITER_2  :   FIELD_B_3   -  FIELD_C_2    -

The iterations 2 and 3 have wrong values in FIELD_C.

How can I find the correct order of the values for the repeated fields ?

I am looking for a solution that does not require manipulating the form definition outside form builder, since the forms will be created by the end user with no knowledge of XForms.

The submit button in properties-local.xml is :

<property
  as="xs:string"
  name="oxf.fr.detail.process.OrbeonFormsPortlet.*.*">
   validate-all
   then send(
         property = "oxf.fr.detail.send.success",
        uri = "http://localhost:8080/web/guest/testlang/-/oaed-form-requests/pop_up/{xxf:get-request-header('Orbeon-Liferay-User-Id')}",
        content = "metadata",
        prune = "false"
    )
</property>

The complete form definition is (the form contains a field - FIELD_A - outside repeated grid which is irrelevant to the problem):

<xh:html xmlns:xh="http://www.w3.org/1999/xhtml"
         xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
         xmlns:ev="http://www.w3.org/2001/xml-events"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:saxon="http://saxon.sf.net/"
         xmlns:xs="http://www.w3.org/2001/XMLSchema"
         xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
         xmlns:fb="http://orbeon.org/oxf/xml/form-builder"
         xmlns:sql="http://orbeon.org/oxf/xml/sql"
         xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
         xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:xf="http://www.w3.org/2002/xforms"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:exf="http://www.exforms.org/exf/1-0">
    <xh:head>
        <xh:title>TestRepeat</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>
                        <FIELD_A/>
                        <grid-3>
                            <grid-3-iteration>

                                <FIELD_B/>
                                <FIELD_C/>

                            </grid-3-iteration>
                        </grid-3>
                    </section-1>
                </form>
            </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="FIELD_A-bind" name="FIELD_A" ref="FIELD_A"/>
                    <xf:bind id="grid-3-bind" ref="grid-3" name="grid-3">
                        <xf:bind id="grid-3-iteration-bind" ref="grid-3-iteration" name="grid-3-iteration">

                            <xf:bind id="FIELD_B-bind" ref="FIELD_B" name="FIELD_B"/>
                            <xf:bind id="FIELD_C-bind" ref="FIELD_C" name="FIELD_C"/>

                        </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>OAED</application-name>
                    <form-name>TestRepeat</form-name>
                    <title xml:lang="en">TestRepeat</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">

                        <FIELD_B>
                            <label>FIELD_B</label>
                            <hint/>
                        </FIELD_B>
                        <FIELD_C>
                            <label>FIELD_C</label>
                            <hint/>
                        </FIELD_C>

                        <section-1>
                            <label>Untitled Section</label>
                        </section-1>
                        <FIELD_A>
                            <label>FIELD_A</label>
                            <hint/>
                        </FIELD_A>
                    </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-3-template">
                <grid-3-iteration>
                    <FIELD_B/>
                    <FIELD_C/>
                </grid-3-iteration>

            </xf:instance>
        </xf:model>
    </xh:head>
    <xh:body>
        <fr:view>
            <fr:body xmlns:oxf="http://www.orbeon.com/oxf/processors"
                     xmlns:p="http://www.orbeon.com/oxf/pipeline"
                     xmlns:xbl="http://www.w3.org/ns/xbl">
                <fr:section id="section-1-control" bind="section-1-bind">
                    <xf:label ref="$form-resources/section-1/label"/>
                    <fr:grid>
                        <xh:tr>
                            <xh:td>
                                <xf:input id="FIELD_A-control" bind="FIELD_A-bind">
                                    <xf:label ref="$form-resources/FIELD_A/label"/>
                                    <xf:hint ref="$form-resources/FIELD_A/hint"/>
                                    <xf:alert ref="$fr-resources/detail/labels/alert"/>

                                </xf:input>
                            </xh:td>
                            <xh:td/>
                        </xh:tr>
                    </fr:grid>
                    <fr:grid id="grid-3-grid" bind="grid-3-bind" repeat="content" min="1"
                             template="instance('grid-3-template')">
                        <xh:tr>

                            <xh:td>
                                <xf:input id="FIELD_B-control" bind="FIELD_B-bind">
                                    <xf:label ref="$form-resources/FIELD_B/label"/>
                                    <xf:hint ref="$form-resources/FIELD_B/hint"/>
                                    <xf:alert ref="$fr-resources/detail/labels/alert"/>

                                </xf:input>
                            </xh:td>
                            <xh:td>
                                <xf:input id="FIELD_C-control" bind="FIELD_C-bind">
                                    <xf:label ref="$form-resources/FIELD_C/label"/>
                                    <xf:hint ref="$form-resources/FIELD_C/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>
</xh:html>

Upvotes: 1

Views: 420

Answers (1)

ebruchez
ebruchez

Reputation: 7857

I do reproduce this, and this appears to be an oversight. Control data is grouped to optimize the output size, but I now see that that can cause problems!

I am not sure that it is possible to infer the order properly given the current structure. I added an issue about this.

Upvotes: 1

Related Questions