Projects‎ > ‎XBL‎ > ‎

XBL Parameters Passing

Rationale

Like standard XForms controls, XBL components need to access "parameters" set in the form of attributes or nested content on the bound node.

The goal of this document is:
  • Illustrate the patterns currently in use in XForms 1.1 and in Orbeon Forms extensions
  • Propose a solution for handling of parameters in XBL

XForms 1.1: values vs. bindings

We identify the following existing XForms 1.1 patterns:
  • Values
    • Use cases: the result is interpreted as a value, typically a string value (but could be any atomic type)
    • Specified by attribute
      • Attribute name should reflect its meaning
      • In this case, the attribute is interpreted as a literal string
        • E.g. <xforms:dispatch name="my-event" ...>
      • NOTE: In Orbeon, we also support AVTs and we think that XForms 1.2 should as well
        • E.g. <xforms:dispatch name="my-{../event-name}" ...>
    • Specified by nested element
      • Element name should reflect its meaning and is the same as the corresponding attribute name
      • This allows using the standard single-node binding attributes plus @value: @model, @context, @ref, @bind, and @value
        • NOTE: XForms 1.1 is not always consistent and does not always allow @value
      • E.g.
        <xforms:dispatch ...>
          <xforms:name ref="instance('my-events')/event-name"/>
    • An element can (and probably should) support both attribute and nested element
  • Single-node bindings
    • Use cases are the regular use cases of single-node binding
      • Reading/writing a value from/to a node specified by the user
      • Reading MIP information from a node including relevant, readonly, valid, required, type, and custom MIPs
    • Specified by attribute
      • E.g. <xforms:submission targetref="/my/node" ...>
      • NOTE: In the example above, for consistency, there could (should?) also be a nested element:
        <xforms:target ref="/my/node"/>
    • Specified by nested element
      • This allows using the standard single-node binding attributes: @model, @context, @ref, @bind (but NOT @value)
      • E.g.
        <xforms:upload ...>
          <xforms:filename bind="my-filename-bind"/>
      • NOTE:  In the example above, for consistency, there could (should?) also be:
        <xforms:upload ... filenameref="@filename">
  • TODO: nodeset bindings
    • These are less common
    • XForms 1.1 has
      • xforms:bind
      • xforms:repeat
      • xforms:itemset
We propose to follow and encourage these patterns for XBL components.

XBL use cases

An XBL component needs:
  • For values (specified as attribute/AVTs and/or specified as nested element):
    • Detect change of that value
    • Pass value to JavaScript during initialization or later
    • Possibly: access to a default for the value
      • At the page level
      • And/or XBL component default
      • And/or global in properties
      • E.g.: Google Maps API key
  • For single-node bindings (specified as attribute and/or specified as nested element):
    • Detect change of node value
    • Pass value to JavaScript during initialization or later
    • Set value from XForms
    • Set value from JavaScript
Example of static value passed as attribute:

<fr:foobar maxlength="12">

Example of AVT value passed as attribute:

<fr:foobar ref="first-name" maxlength="{if (@maxlength) then @maxlength else 50}">

Example of nested element:

<fr:foobar ref="first-name">
  <fr:maxlength value="if (@maxlength) then @maxlength else 50"/>

Example of read/write value passed as attribute:

<fr:foobar maxlengthref="/my/maxlength">

Example of read/write value passed as attribute with bind:

<fr:foobar maxlengthbind="my-maxlength-bind">

Example of nested element:

<fr:foobar ref="first-name">
  <fr:maxlength ref="@maxlength"/>

Example of nested element with bind:

<fr:foobar ref="first-name">
  <fr:maxlength bind="my-maxlength-bind"/>

NOTE: Using maxlength-ref and maxlength-bind would be more readable.

Mechanisms for the XBL component author

Thoughts:
  • Doing everything "by hand" using xbl:content, xbl:attr, xxbl:transform, or variables, is painful!
  • Proposed
    • xxforms:evaluate-avt() to facilitate evaluation of AVTs [IMPLEMENTED ALREADY]
    • xxforms:xbl-attr() to access the value of a bound node attribute from XPath at runtime
  • Mechanisms needed
    • Easy way of handling nested elements
    • Easy way of detecting changes to values (as opposed to nodes)
  • [TODO]

Example of <fr:data-bound-select1>

The dependency can be written with a nested element:

<fr:data-bound-select1 ref="city" resource="/xforms-sandbox/service/zip-cities?state-abbreviation={state}">
    ...
    <fr:dependency ref="../state"/>
</fr:data-bound-select1>

This is equivalent to:

<fr:data-bound-select1 ref="city"
      resource="/xforms-sandbox/service/zip-cities?state-abbreviation={state}"
      dependency-ref="state">
    ...
</fr:data-bound-select1>

NOTE: Should dependency-ref be relative to ref?


This is also equivalent to:

<fr:data-bound-select1 ref="city">
    ...
    <fr:resource value="
concat('/xforms-sandbox/service/zip-cities?state-abbreviation=', ../state)"/>
    <fr:dependency ref="../state"/>
</fr:data-bound-select1>

XBL properties brainstorm 2009-04-15

With values:
  • 4 levels
    • default value on component: <xbl:binding><xxbl:property name="initial-zoom" value="5" as="xs:integer"/>
    • properties.xml: (oxf|orbeon).xforms.xbl.fr.map.initial-zoom
    • document (on xforms:model): <xforms:model xxforms:xbl.fr.map.initial-zoom="4">
    • user-specified value as attribute on bound element: <fr:map initial-zoom="5">
  • Using the property
    • <xforms:output value="property('xxbl:initial-zoom')"><xxforms:script ev:event="xforms-value-changed">...
    • OR: <xforms:output value="property('xxbl:initial-zoom', 5, 'xs:integer')"><xxforms:script ev:event="xforms-value-changed">...

Comments