Search code examples
orbeonxforms

Orbeon: readony instance affecting the form links depending on the position in the model with respect to other instances


I have come across a strange defect. I am using Orbeon 3.9 CE on Tomcat. Depending on the text-field value='true' the link will be shown as in the screenshot. Please note the trigger refer to "data-safe" instance for showing and hiding.

<xforms:trigger appearance="minimal" ref=".[instance('data-safe')/data-safe='true']">
    <xforms:label>
        Add
    </xforms:label>
</xforms:trigger>

This is how the screen should look like.
expected functionality

Now, for as part of performance improvements, i have one of the instance with the attribute xxforms:readonly="true"

1st instance read-only

Here the 1st instance is readonly

then the form displayed changes to like below. where the add link is disabled. add link disabled

now if i change the order of the readonly instance from 1st position in the model to somewhere below. like shown readonly moved below

the add link gets enabled
expected functionality

here is a code sample to explain the issue

  <xhtml:head>

    <xhtml:title>SO question</xhtml:title>
    <!-- CSS StyleSheet test-->

    <!-- Link to the Model goes Here -->
    <!-- Needs exslt to do some fancy things with Dates and Time -->
    <xforms:model id="model">

        <!-- -->
        <!-- Places Instances Here -->
        <!-- -->


        <xforms:instance id="dropdown-values"   src="oxf:/apps/TSDM/global_instances/Dropdown-Values.xml" xxforms:readonly="true"/>

        <xforms:instance id="form-attributes">
            <attributes>
                <form-global>
                    <current-page>1</current-page> <!-- Always starts on 1 -->
                    <previous-page></previous-page> <!-- Always starts on 1 -->
                    <next-page></next-page> <!-- Always starts on 1 -->
                    <first-page>1</first-page> <!-- First Page Boundary: 1 always -->
                    <last-page>12</last-page> <!-- Last Page Boundary: Change based on form -->
                    <summary>false</summary> <!-- Enable Summary View indicator -->
                </form-global>
            </attributes>
        </xforms:instance>

        <xforms:instance id="data-safe">
            <flag>
                <data-safe>true</data-safe>
                <data-safe1></data-safe1>
            </flag>
        </xforms:instance>

    <xforms:bind id="group-level-specifications-credit-effective-end-date" nodeset="instance('data-safe')/data-safe"
                    calculate="."
                    readonly="false()"/>


    <!--xforms:bind nodeset="instance('data-safe')/data-safe1" type="xforms:date"
                    calculate="months(xforms:dayTimeDuration(../data-safe))"
                    readonly="false()"/-->

    </xforms:model>


</xhtml:head>
<!-- End of Head -->



<!-- Start of the Body of the Page -->
<xhtml:body class="MainBODY">

    <xforms:switch>
        <xforms:case>
            <xforms:trigger appearance="minimal" ref=".[instance('data-safe')/data-safe='true']">
                <xforms:label>
                    Add
                </xforms:label>

            </xforms:trigger>
        </xforms:case>
    </xforms:switch>
    <xforms:input ref="instance('data-safe')/data-safe" />
    <br/>
    <xforms:input ref="instance('data-safe')/data-safe1" />


</xhtml:body>

Solution

  • When you write <xforms:trigger ref=".[some condition]">, you are not only hiding the trigger when the condition is false, you are also binding it to whatever node . points to. Unless your trigger is inside some container element (<xforms:group>, …) which changes the context, the context is the root element of the first instance. When a trigger is bound to a node:

    1. The trigger won't show if the node is non-relevant.
    2. The trigger shows as disabled if the node is read-only.

    You are in this second case, not because of an <xforms:bind readonly="false()"/> in your code, but because when you put an xxforms:readonly="true" on an instance, all its nodes are marked as readonly.

    The solution in your case is simple: move that instance as the second one, as you did, or bind the trigger to another node that isn't read-only by using another XPath expression instead of ..