Search code examples
orbeonxforms

XForms: inserting a subitem for all list item with a cycle


If I have a XForms instances like

<xforms:instance id="myvrs">
    <myvrs>
        <subitem />
    </myvrs>
</xforms:instance>
<xforms:instance id="tmp">
    <temp>
        <item><subitem>11</subitem></item>
        <item><subitem>21</subitem><subitem>22</subitem></item>
        <item></item>
    </temp>
</xforms:instance>

How to use a cycle like

<xforms:trigger>
    <xforms:label>button</xforms:label>
    <xforms:action events:event="DOMActivate">
    forall in instance('tmp')/item
        <xforms:insert context="instance('tmp')/item" origin="instance('myvrs')/subitem" />
    endforall
    </xforms:action>
</xforms:trigger>

That i can get instance

<xforms:instance id="tmp">
    <temp>
        <item><subitem>11</subitem><subitem></subitem></item>
        <item><subitem>21</subitem><subitem>22</subitem><subitem></subitem></item>
        <item><subitem></subitem></item>
    </temp>
</xforms:instance>

Thank you


Solution

  • To iterate in XForms 1.1 you need to use the while attribute (see 10.18 Iteration of XForms Actions).

    In your case that can be done with an additional instance:

    <xf:instance id="iterator">
        <iterator xmlns=""></iterator>
    </xf:instance>
    

    And the action could then be:

    <xf:action ev:event="DOMActivate">
        <xf:setvalue ref="instance('iterator')" value="1"></xf:setvalue>
        <xf:action while="instance('iterator') &lt; count(instance('tmp')/item)">
            <xf:insert context="instance('tmp')/item[position()=instance('iterator')]"
                origin="instance('myvrs')/subitem" nodeset="subitem" position="after"></xf:insert>
            <xf:setvalue ref="instance('iterator')" value="instance('iterator') + 1"></xf:setvalue>
        </xf:action>
    </xf:action>
    

    Note that this is standard XForms 1.1 and that should work with other implementations.

    The full XForms would be:

    <html xmlns:xf="http://www.w3.org/2002/xforms" xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
        <head>
            <title>Insert for all</title>
            <xf:model>
                <xf:instance id="myvrs">
                    <myvrs xmlns="">
                        <subitem></subitem>
                    </myvrs>
                </xf:instance>
                <xf:instance id="tmp">
                    <temp xmlns="">
                        <item>
                            <subitem>11</subitem>
                        </item>
                        <item>
                            <subitem>21</subitem>
                            <subitem>22</subitem>
                        </item>
                        <item></item>
                    </temp>
                </xf:instance>
                <xf:instance id="iterator">
                    <iterator xmlns=""></iterator>
                </xf:instance>
            </xf:model>
        </head>
        <body>
            <xf:trigger>
                <xf:label>button</xf:label>
                <xf:action ev:event="DOMActivate">
                    <xf:setvalue ref="instance('iterator')" value="1"></xf:setvalue>
                    <xf:action while="instance('iterator') &lt; count(instance('tmp')/item)">
                        <xf:insert context="instance('tmp')/item[position()=instance('iterator')]"
                            origin="instance('myvrs')/subitem" nodeset="subitem" position="after"></xf:insert>
                        <xf:setvalue ref="instance('iterator')" value="instance('iterator') + 1"></xf:setvalue>
                    </xf:action>
                </xf:action>
            </xf:trigger>
            <fr:xforms-inspector xmlns:fr="http://orbeon.org/oxf/xml/form-runner"></fr:xforms-inspector>
        </body>
    </html>