Orbeon Forms
  • Getting started
  • Installation
    • Logging
    • Configuration banner
    • Docker
    • Azure
    • Tomcat
    • WildFly
    • WebSphere
    • WebLogic
    • GlassFish
    • Caches
    • Replication
    • Upgrading
  • Configuration
    • Properties
      • General
        • HTTP client
      • Form Runner
        • Detail page
          • Attachments
          • Email
          • PDF
          • Table of contents
        • Persistence
        • Summary page
      • Form Builder
      • XForms
    • Advanced
      • Workflows
      • Session management
      • State handling
      • Client-side error handling
      • Clustering and High Availability
      • Configuring a Form Runner eXist database
      • Creating a production WAR
      • Environments
      • JavaScript and CSS assets
      • Limiter filter
      • Run modes
      • Security
        • Content-Security-Policy header
      • SAP Hybris Module
      • XForms logging
    • Troubleshooting
      • Troubleshooting with the orbeon.log
      • Memory and threads
      • Relational database logging
      • Misc
  • Form Builder
    • Form settings
      • Time window
    • Form editor
      • Form area
      • Toolbox
      • Buttons bar
      • Control settings
      • Dependent fields and sections
      • Validation
      • Choices editor
      • Publishing
      • Cut, copy and paste
      • Section and grid settings
      • Section settings
      • Grid settings
      • Quick control search
      • Repeat settings
      • Repeated grids
      • Undo and redo
      • Keyboard shortcuts
    • Formulas
      • Examples of formulas
      • Formulas inspector
      • Formulas console
    • Summary page
    • Form localization
    • Advanced
      • Edit source
      • Services and actions
        • HTTP services
        • Database services
        • Simple Actions
        • Action Syntax
        • Action Syntax examples
        • Synchronizing repeated content
      • Testing a form in web mode
      • Testing PDF production
      • Testing offline functionality
      • Email settings
      • Field-level encryption
      • Messages
      • Section templates
      • Template syntax
      • XML Schemas support
      • Extensibility
        • Extension API
        • Integration
        • Toolbox component metadata
  • Form Runner
    • Overview
      • Terminology
    • Pages
      • Landing page
      • Published Forms page
      • Forms Admin page
      • Summary page
    • Components
      • Alert dialog
      • Attachment
      • Autocomplete
      • Captcha
      • Character counter
      • Checkbox input
      • Currency
      • Date
      • Dropdown date
      • Static and dynamic dropdown
      • Error summary
      • Grid
      • Handwritten signature
      • Hidden field
      • Image
      • Image annotation
      • Image attachment
      • Number
      • Open selection
      • Repeater
      • Formatted Text / Rich Text Editor
      • Section
      • Single-selection tree
      • Source code editor
      • Time
      • US phone
      • US state
      • Video
      • Video attachment
      • Wizard
      • XForms inspector
      • Yes/No answer
    • Features
      • Automatic calculations dependencies
      • Datasets
      • Excel and XML import
      • Excel and XML export
      • Summary page Excel Export
      • Form definitions and form data Zip Export
      • Purging historical data
      • Lease
      • Localization
      • Supported languages
      • Mobile support
      • Multitenancy
      • Form Runner navigation bar
      • PDF production
        • Automatic PDF
        • Automatic PDF header and footer configuration
        • PDF templates
      • Responsive design
      • Revision history
      • S3 storage
      • Simple data migration
      • TIFF production
      • Versioning
      • Wizard view
      • Workflow stage
    • Persistence
      • Using a relational database
      • Relational database schema
      • Purging old data using SQL
      • Auditing
      • Autosave
      • Database support
      • Flat view
    • Linking and embedding
      • Linking
      • Java Embedding API
      • JavaScript Embedding API
      • Liferay full portlet
      • Liferay proxy portlet
      • Securing Form Runner access
      • Form Runner offline embedding API
      • Angular component
      • React component
    • Access control and permissions
      • Users
      • Login & Logout
      • Deployed forms
      • Form fields
      • Editing forms
      • Owner and group member
      • Organizations
      • Scenarios
      • Token-based permissions
    • Styling
      • CSS
      • Grids CSS
      • Automatic PDF styling and CSS
    • APIs
      • Authentication of server-side service APIs
      • Persistence API
        • CRUD API
        • Search API
        • List form data attachments API
        • Form Metadata API
        • Lease API
        • Reindexing API
        • Caching
        • Versioning
        • Revision History API
        • Zip Export API
        • Custom persistence providers
      • Other APIs
        • Connection context API
        • Duplicate form data API
        • File scan API
        • Form Runner JavaScript API
        • Generate XML Schema API
        • PDF API
        • Publish form definition API
        • Run form in the background API
      • Data formats
        • Form data
        • Date and time
        • Form definition
    • Architecture and integration
      • Architecture
      • Access form data
      • Integration
    • Advanced
      • Buttons and processes
        • Simple process syntax
        • Core actions
        • Form Runner actions
          • Save action
          • Send action
          • Email action
        • XForms actions
        • Predefined buttons, processes and dialogs
        • Summary page buttons and processes
      • Custom dialogs/model logic
      • Services
      • Singleton form
      • Monitoring HTTP requests
  • XForms
    • Core
      • Attribute Value Templates (AVTs)
      • Binds
      • Validation
      • Variables
      • Keyboard focus
      • XForms JavaScript API
      • Error handling
        • Detailed behavior
      • Model-Bind variables
      • XForms 2.0 support
    • Events
      • Standard support
      • UI refresh events
      • Keyboard events
      • Extension events
      • Extension context information
      • Other event extensions
    • Actions
      • Repeat, insert and delete
      • Scripting actions
      • Extensions
    • Controls
      • Label, hint, help
      • Input
      • Output
      • Text area
      • Button
      • Upload
      • Dialog
    • Submission
      • Standard support
      • JSON support
      • Asynchronous submissions
      • Caching extension
      • Other submission extensions
    • XPath
      • Type annotations
      • Expression analysis
      • Tips
      • Compatibility
      • Standard functions
      • Maps and arrays Functions
      • Extension functions
        • Core functions
        • Utility functions
        • Model functions
        • Controls functions
        • XML functions
        • JSON functions
        • HTTP functions
        • Form Runner functions
        • Other functions
        • Deprecated functions
    • XBL components
      • FAQ
      • Guide
        • XBL Tutorial
        • Bindings
        • XForms models
        • Including content
        • Event handling
        • Conventions
        • Map XBL example
        • Learning from existing components
      • Advanced topics
        • XBL Modes
        • JavaScript companion classes
        • XBL library
        • Extensions
        • Attachment controls
    • XForms tutorial
      • Introduction
      • Installation
      • The Hello application
      • The Bookcast application
        • The basic app
        • Database access
        • Polishing the app
        • Adding a feed
    • Using XForms from Java apps
  • XML Platform
    • Page Flow Controller
      • Basics
      • XML submission
      • Navigating between pages
      • Paths and matchers
      • Other configuration elements
      • Typical combinations of page model and page view
      • Examples
      • Authorizing pages and services
    • Processors
      • URL generator
      • Request generator
      • PDF to image converter
    • Resources
      • Resource managers
      • Setting up an external resources directory
    • Other
      • Binary and text documents
  • FAQ
    • Licensing
    • PE and Dev Support
    • Form Builder and Form Runner
    • Resources and support
    • Other technical questions
  • Contributors
    • Automated tests
    • Building Orbeon Forms
    • Localizing Orbeon Forms
    • Validation functions
    • Contributor License Agreement
  • Release notes
    • Orbeon Forms 2022.1.9
    • Orbeon Forms 2024.1.1
    • Orbeon Forms 2023.1.7
    • Orbeon Forms 2024.1
    • Orbeon Forms 2023.1.6
    • Orbeon Forms 2023.1.5
    • Orbeon Forms 2021.1.11
    • Orbeon Forms 2022.1.8
    • Orbeon Forms 2023.1.4
    • Orbeon Forms 2023.1.3
    • Orbeon Forms 2023.1.2
    • Orbeon Forms 2022.1.7
    • Orbeon Forms 2023.1.1
    • Orbeon Forms 2023.1
    • Orbeon Forms 2022.1.6
    • Orbeon Forms 2021.1.10
    • Orbeon Forms 2022.1.5
    • Orbeon Forms 2021.1.9
    • Orbeon Forms 2022.1.4
    • Orbeon Forms 2022.1.3
    • Orbeon Forms 2021.1.8
    • Orbeon Forms 2022.1.2
    • Orbeon Forms 2022.1.1
    • Orbeon Forms 2022.1
    • Orbeon Forms 2021.1.7
    • Orbeon Forms 2021.1.6
    • Orbeon Forms 2021.1.5
    • Orbeon Forms 2021.1.4
    • Orbeon Forms 2021.1.3
    • Orbeon Forms 2021.1.2
    • Orbeon Forms 2021.1.1
    • Orbeon Forms 2021.1
    • Orbeon Forms 2020.1.6
    • Orbeon Forms 2019.2.4
    • Orbeon Forms 2019.1.2
    • Orbeon Forms 2018.2.5
    • Orbeon Forms 2018.1.4
    • Orbeon Forms 2020.1.5
    • Orbeon Forms 2020.1.4
    • Orbeon Forms 2020.1.3
    • Orbeon Forms 2020.1.2
    • Orbeon Forms 2019.2.3
    • Orbeon Forms 2020.1.1
    • Orbeon Forms 2020.1
    • Orbeon Forms 2019.2.2
    • Orbeon Forms 2019.2.1
    • Orbeon Forms 2019.1.1
    • Orbeon Forms 2019.2
    • Orbeon Forms 2019.1
    • Orbeon Forms 2018.2.4
  • Release history
  • Use cases
  • Product roadmap
  • Index of features
Powered by GitBook
On this page
  • Encapsulation
  • The default: strong encapsulation
  • Creating a single-node binding
  • Adding support for a value
  • Adding LHHA elements
  • A basic component
  • Using local state
  1. XForms
  2. XBL components
  3. Guide

XBL Tutorial

Encapsulation

The component system favors a strong encapsulation so that components can be:

  • developed in isolation, without knowing the details of the application using them

  • used without knowing the details of how they are implemented

  • in short: reused as much as possible!

The goal is first eased of use and transparency for the form author. This means that sometimes the component author must do a little bit more work!

The default: strong encapsulation

By default, within an <xbl:binding> element, encapsulation is strong: this means that XForms controls, models, and event handlers cannot:

  • see ids of the XForms document using the component

  • have access to the XPath context outside the component

In other words, things behave as if you were working in a new, completely separate XForms document!

If you place models within <xbl:implementation> or <xbl:template>, the same rule that applies in a top-level XForms document apply:

  • The default XPath context starts with the root element of the first instance of the first model.

  • However, if your component doesn't have a model, then the XPath context is set to an empty document node.

    • NOTE: In the future, this might change to being an empty sequence. For implementation-dependent reasons, for now an empty document node had to be used.

Creating a single-node binding

Orbeon Forms provides direct support for bindings with the binding mode:

<xbl:binding id="fr-foo" element="fr|foo" xxbl:mode="binding">

This automatically means that the component supports all the XForms binding attributes, including ref and bind, and UI events such as xforms-enabled / xforms-disabled and others are dispatched as needed.

You can access the actual bound node via the xxf:binding() function:

xxf:binding('fr-foo')

The id passed must be the id of the xbl:binding element.

Adding support for a value

Some native XForms controls, like xf:input, xf:textarea, etc. support holding a value. This means in particular that the control is able to dispatch xforms-value-changed events. Some controls on the other hand, like xf:group, xf:repeat, can't hold a value and don't dispatch xforms-value-changed events.

The default for XBL components is that they don't hold a value. Use the value mode to add value behavior:

<xbl:binding
  id="fr-phone-binding"
  element="fr|us-phone"
  xxbl:mode="lhha binding value">

The xxf:value() function allows access to the control's value from the inside, by using the binding id:

<xbl:binding id="fr-gaga" element="fr|gaga" xxbl:mode="binding value">
    <xbl:template>
        <xf:output id="gaga-output" value="xxf:value('fr-gaga')"/>
    </xbl:template>
</xbl:binding>

Adding LHHA elements

Orbeon Forms provides direct support for label, help, hint and alert (LHHA):

<xbl:binding id="fr-foo" element="fr|foo" xxbl:mode="lhha">

This automatically adds support for LHHA to the component:

<fr:foo>
    <xf:label>My label</xf:label>
    ...
</fr:foo>

By default, markup is output for the LHHA elements. You can disable this with the custom-lhha mode:

<xbl:binding id="fr-foo" element="fr|foo" xxbl:mode="lhha custom-lhha">

With this mode, no markup is output, and the component author can access the LHHA values with XPath functions:

<xf:output value="xxf:label('fr-foo')"/>

[SINCE Orbeon Forms 4.5] When using the lhha mode, it is possible to link the label handled by the XBL engine to an internal control, so that that control and the label are linked. This is done with the xxbl:label-for attribute:

<xbl:binding
  id="fr-dropdown-select1"
  element="fr|dropdown-select1"
  xxbl:container="span"
  xxbl:mode="lhha binding value"
  xxbl:label-for="select1">

<xbl:template>
    <xf:select1
        appearance="minimal"
        ref="xxf:binding('fr-dropdown-select1')"
        id="select1">
    ...

A basic component

You can find the component discussed in this section in the Orbeon Forms distribution:

Orbeon Forms modes make this very simple:

<xbl:xbl
    xmlns:xh="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
    xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
    xmlns:xbl="http://www.w3.org/ns/xbl"
    xmlns:xxbl="http://orbeon.org/oxf/xml/xbl">

    <xbl:binding
        element="fr|tutorial-input"
        id="fr-tutorial-input"
        xxbl:mode="lhha binding value">
        <xbl:template>
            <!-- Input points to the external single-node binding -->
            <xf:input ref="xxf:binding('fr-tutorial-input')"/>
        </xbl:template>
    </xbl:binding>
</xbl:xbl>

Using local state

You can find the component discussed in this section in the Orbeon Forms distribution:

  • XBL: xbl/orbeon/tutorial-davinci/tutorial-davinci.xbl

  • Example: apps/xforms-sandbox/samples/xbl-tutorial-davinci.xhtml

Now assume you would like to write a component which stores the string of characters entered by the user but back to front, i.e. reversed. If the user types "Amelia", the string stored in the instance will be "ailemA".

How would you go about this? The binding between an XForms control and instance data is direct: the value entered by the user is stored into the instance as soon as the user moves out of the field, and you can't just write a transformation in between. So we need some intermediate state to store the value entered by the user.

To do so, we create a local instance. You can put it under the <xbl:implementation> or <xbl:template> elements in your XBL file:

<xf:model>
    <xf:instance><value/></xf:instance>
</xf:model>

Here we store a single value, so we just use a single root element in the instance: <value>.

The local input field just points to the local instance instead of pointing to the external single-node binding:

<xf:input ref="instance()">

So here, the input field points to the <value> element.

NOTE: You could also write ref=".", which would work because, like at the top-level of an XForms document, the default XPath context is the root element of the first instance in the first model. Using instance() is a bit more explicit.

What is needed now is, when the local value changes, to copy it to the external single-node binding. You do so with an event handler:

<xf:input ref="instance()">
    <xf:setvalue
        event="xforms-value-changed"
        ref="xxf:binding('fr-tutorial-davinci')"
        value="context()"/>
</xf:input>

What's missing now is to reverse the value:

<xf:input ref="instance()">
    <xf:setvalue
        event="xforms-value-changed"
        ref="xxf:binding('fr-tutorial-davinci')"
        value="
            codepoints-to-string(
                reverse(
                    string-to-codepoints(
                       instance()
                    )
                )
            )
        "/>
</xf:input>

Finally, the opposite operation is needed: when the component first comes to life, and when the external value changes, the internal value must update:

<xbl:handler
    event="xforms-enabled xforms-value-changed"
    ref="instance()"
    value="
        codepoints-to-string(
            reverse(
                string-to-codepoints(
                    xxf:binding('fr-tutorial-davinci')
                )
            )
        )
 "/>

So here you go: you have a fully working non-trivial component:

<xbl:xbl
    xmlns:xh="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
    xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
    xmlns:xbl="http://www.w3.org/ns/xbl"
    xmlns:xxbl="http://orbeon.org/oxf/xml/xbl">

    <xbl:binding
        element="fr|tutorial-davinci"
        id="fr-tutorial-davinci"
        xxbl:mode="lhha binding value">
        <xbl:handlers>
            <!-- When the control comes to life or its value changes, copy
                 the new value to the local model after reversing it -->
            <xbl:handler
                event="xforms-enabled xforms-value-changed"
                ref="instance()"
                value="
                    codepoints-to-string(
                        reverse(
                            string-to-codepoints(
                                xxf:binding('fr-tutorial-davinci')
                            )
                        )
                    )
                "/>
        </xbl:handlers>
        <xbl:template>
            <!-- Local model and instance -->
            <xf:model>
                <xf:instance><value/></xf:instance>
            </xf:model>
            <!-- Input points to the internal value -->
            <xf:input ref="instance()">
                <!-- When the local value changes, copy it to the external
                     single-node binding after reversing it -->
                <xf:setvalue
                    event="xforms-value-changed"
                    ref="xxf:binding('fr-tutorial-davinci')"
                    value="
                        codepoints-to-string(
                            reverse(
                                string-to-codepoints(
                                    instance()
                                )
                            )
                        )
                    "/>
            </xf:input>
        </xbl:template>
    </xbl:binding>
</xbl:xbl>
PreviousGuideNextBindings

Last updated 5 years ago

For more, see .

XBL:

Example:

tutorial-input.xbl
xbl-tutorial-input.xhtml
The binding mode