Projects‎ > ‎

XForms - Model Scoping Rules Proposal

NOTE: This page describes an Orbeon Forms project, not a feature which is currently part of Orbeon Forms.

Rationale

In XForms 1.1:
  • xforms:model is strictly a top-level elements. It cannot (or is not really designed to be) be embedded within other XForms elements
  • visibility is not lexical: models live in a separate space ("model"), and controls in another ("view")
Now, XForms components need to include local models. Questions arise:
  • Do they have visibility on "outer" XForms, in particular:
    • variables
    • elements resolved by id, as with the @model attribute
  • How do controls placed at the level of such models see them?
  • Do they influence the in-scope XPath evaluation context?
  • Etc.

Proposal

Top-level models:
  • models within xhtml:head
  • models within xbl:implementation
  • follow "special" rules as dictated by XForms 1.1
      • any control or AVT placed at the top-level
        • is by default within the scope of the first model (first model + first instance of that model rule)
        • can override this behavior using the @model attribute
      • by default, top-level models do not have visibility on any controls or variables outside of themselves
      • xbl:scope="outer" could be interpreted within local XBL models
        • access to outer variables
        • access to outer ids
    • 2011-11-15 NOTE: might not need "special rule" besides "if top-level control and no explicit model, take first top-level model".
    Nested models:
    • all other models, i.e. under xhtml:body or xbl:template
    • follow new rules of lexical scoping
        • can be nested within XForms or XBL markup
          • do not influence the in-scope evaluation context for controls
            • @model is needed to refer to those nested models
          • control or action $X can only view $X/ancestor-or-self::*/preceding-sibling::xforms:model
            • Q: should we introduce xforms:model/@name?
            • A: would be desirable to indicate better the scoping rule, like with xxf:variable
          • model content sees in-scope variables
            • handle issue of model RRR when in-scope variables change

        How this applies to components

        Example

        <xbl:template>
            <!-- Variable sees the context where the component is instantiated -->
            <xxforms:variable name="current" xbl:attr="select=ref" as="node()?"/>
            <xforms:model id="my-nested-model">
                <xforms:instance id="my-nested-instance">
                    <value/>
                </xforms:instance>
                <!-- Action sees 1st instance of current model by default, but also sees outer variable -->
                <xforms:setvalue ev:event="xforms-model-construct-done" ref="." value="$current"/>
            </xforms:model>
            <!-- Control sees the context where the component is instantiated so same a ref="$current" -->
            <xforms:input xbl:attr="ref"/>
            <!-- Points to the "value" element of the nested model -->
            <xforms:input model="my-nested-model" ref="."/>
        </xbl:template>

        NOTE: The above does not yet work in Orbeon Forms as of 2009-10-09.

        Scoping within xxforms:dialog

        The new scoping rules require a departure from the pattern currently in use (e.g. in Form Builder):

        <xxforms:dialog model="my-model">
            <xforms:label>My Dialog</xforms:label>
            <xhtml:div>
                <xforms:group>
                    ...
                </xforms:group>
            </xhtml:div>

            <xforms:action ev:event="xxforms-dialog-open">
                ...

            </xforms:action>

            <xforms:model id="my-model">
                <xforms:instance id="my-instance">
                    <instance>
                        ...
                    </instance>
                </xforms:instance>
            </xforms:model>
        </xxforms:dialog>

        Here is the new pattern to use:

        <xxforms:dialog>
            <xforms:label>My Dialog</xforms:label>

            <xforms:model id="my-model">
                <xforms:instance id="my-instance">
                    <instance>
                        ...
                    </instance>
                </xforms:instance>
            </xforms:model>

            <xforms:group model="my-model">
                ...
            </xforms:group>

            <xforms:action ev:event="xxforms-dialog-open">
                ...
            </xforms:action>

        </xxforms:dialog>

        Instance Scoping with xxforms:instance()

        Before XBL, search occurred only on top-level models. Now, there can be many local instances with the same identifier in multiple component instances, including in repeats (when supported).

        With XBL, the rules change as follows:
        • no search in sibling or descendant components
        • search ancestor-or-self components up to top-level

        Comments