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 properties
          • 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 dialog
      • 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
      • International Securities Identification Number (ISIN)
      • Legal Entity Identifier (LEI)
      • Number
      • Open selection
      • Repeater
      • Formatted Text / Rich Text Editor
      • Section
      • Single-selection tree
      • Source code editor
      • Time
      • US Employer Identification Number (EIN)
      • US phone
      • US Social Security Number (SSN)
      • 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
  • Getting started
  • XForms model and instance
  • First controls
  • Adding constraints
  • Single selection controls
  • Adding a text area
  • Finishing-up the controls
  1. XForms
  2. XForms tutorial
  3. The Bookcast application

The basic app

Getting started

But first things first. Start by making a first functional page:

  • The first thing to do is to create a new directory for your application. Orbeon Forms already come with the complete xforms-bookcast application, so instead let's decide on another name, for example my-bookcast. Create a directory with that name as RESOURCES/apps/my-bookcast. For convenience, we refer to that new directory as the BOOKCAST directory below.

  • Create a page-flow.xml file under BOOKCAST:

      <controller xmlns="http://www.orbeon.com/oxf/controller">
          <page path="/my-bookcast/" view="view.xhtml"/>
          <epilogue url="oxf:/config/epilogue.xpl"/>
      </controller>

This page flow is automatically called for any path that starts with /orbeon/my-bookcast/. Here, it matches on the exact path /orbeon/my-bookcast/ and calls up the page view called view.xhtml.

  • Create a skeleton for your view.xhtml under BOOKCAST:

      <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xxf="http://orbeon.org/oxf/xml/xforms">
          <head>
              <title>XForms Bookcast</title>
          </head>
          <body>
              <p>Hello!</p>
          </body>
      </html>

    This is a very basic XHTML document. It features a title in the <head> and a "Hello!" message in the <body>. It also declares a bunch of XML namespaces that you need later in the document.

Now go to:

http://localhost:8080/orbeon/my-bookcast/

You should see something like this:

NOTE:

If you get lost at some point in this tutorial, feel free to look at the reference source files for the Bookcast application:

XForms model and instance

An XForms document that wants to do something really useful needs at least one model containing one instance. But first it is wise to decide how you would like to represent the information captured by your form. This is an example that shows a possible representation of the data of the Bookcast application (notes are borrowed from Wikipedia and are under the GNU Free Documentation License):

<books>
    <book>
        <title>Don Quixote de la Mancha</title>
        <author>Miguel de Cervantes Saavedra</author>
        <language>es</language>
        <link>http://en.wikipedia.org/wiki/Don_Quixote</link>
        <rating>5</rating>
        <notes>
            The book tells the story of Alonso Quixano, a man who has read so many stories about
            brave errant knights that, in a half-mad and confused state, he believes himself to be a
            knight, re-names himself Don Quixote de la Mancha, and sets out to fight injustice in
            the name of his beloved maiden Aldonsa, or as he knows her in his mind, Dulcinea del
            Toboso.
        </notes>
    </book>
    <book>
        <title>Jacques le fataliste et son maître</title>
        <author>Denis Diderot</author>
        <language>fr</language>
        <link>http://en.wikipedia.org/wiki/Jacques_le_fataliste_et_son_ma%C3%AEtre</link>
        <rating>5</rating>
        <notes>
            Ce roman complexe et déconcertant — sans doute l'œuvre de Diderot la plus commentée —
            puise pour partie son inspiration dans l'ouvrage de Laurence Sterne, Vie et opinions de
            Tristram Shandy paru quelques années auparavant (1759-1763).
        </notes>
    </book>
    <book>
        <title>Childhood's End</title>
        <author>Arthur C. Clarke</author>
        <language>en</language>
        <link>http://en.wikipedia.org/wiki/Childhood%27s_End</link>
        <rating>5</rating>
        <notes>
            Childhood's End deals with humanity's transformation and integration into an
            interplanetary hive mind. The book also touches on the issues of the Occult, man's
            inability to live in a utopian society, and cruelty to animals, as well as the cliché of
            being the last man on Earth.
        </notes>
    </book>
    <book>
        <title>The Demon-Haunted World</title>
        <author>Carl Sagan</author>
        <language>en</language>
        <link>http://en.wikipedia.org/wiki/The_Demon-Haunted_World</link>
        <rating>5</rating>
        <notes>
            Sagan states that when new ideas are offered for consideration, they should be tested
            by means of skeptical thinking, and should stand up to rigorous questioning.
        </notes>
    </book>
</books>

As you can see, the idea is to store the information about all the books in a single XML document. So under a top-level <books> element, we put as many <book> children elements as needed. You will see later how it is possible with XForms to add and remove children elements. For now, your initial instance declaration is empty and contains a single book, and you place it as usual within an <xf:model> element:

<xf:model>
    <xf:instance id="books-instance">
        <books xmlns="">
            <book>
                <title/>
                <author/>
                <language/>
                <link/>
                <rating/>
                <notes/>
            </book>
        </books>
    </xf:instance>
</xf:model>

Notice the id attribute which allows other XForms constructs to refer to that particular instance.

Now do the following:

  • Insert the model and instance under the <head> element.

  • Reload the page.

You should still see a blank page, because so far you haven't added any visual elements!

First controls

Now it's time to add some visual controls to your page. Start with the following under the <body> element:

<xf:group ref="book">
    <xf:input ref="title">
        <xf:label>Title</xf:label>
    </xf:input>
    <br/>
    <xf:input ref="author">
        <xf:label>Author</xf:label>
    </xf:input>
</xf:group>

Reload the page. You should see something like this:

Another thing: all XForms controls require a nested <xf:label> element, as an effort to help accessibility. In some cases, you won't want an actual label to display next to the control: to achieve this, you can either hide the label with CSS, or use an empty label element (<xf:label/>).

Adding constraints

Now say you want to make the title and author required data. You control this with the <xf:bind> element in the XForms model. Add the following under <xf:model> after your instance:

<xf:bind ref="book">
    <xf:bind ref="title" required="true()"/>
    <xf:bind ref="author" required="true()"/>
</xf:bind>

Notice how, as you enter text in the title or author field, the field's background changes color to indicate that the field must be filled out.

The above requires some explanations:

  • Here we use the required attribute, which determines whether a field is, well, required, that is, whether it has to be filled out by the user.

  • Much like <xf:group> in the controls, <xf:bind> elements can be nested.

  • <xf:bind> uses a ref attribute, which allows pointing at more than one node using a single XPath expression.

  • The outer <xf:bind> element points to the <book> element under the top-level <books> element of your instance. This happens because the evaluation context for a top-level XPath expression in an <xf:bind> element is the root element of the first XForms instance. You could be more explicit, for example with:

      <xf:bind ref="/books/book">
          ...
      </xf:bind>

    Or with:

      <xf:bind ref="instance('books-instance')/book">
          ...
      </xf:bind>

    The latter makes it clear, with the XForms instance() function, that you are addressing the books-instance instance and not another instance, so you will probably tend to prefer that notation.

  • The inner <xf:bind> elements apply the required MIP to the <title> and <author> elements. The required attribute must contain an XPath expression, which is why it contains true() (the way to express a Boolean "true" value in XPath) and not simply true. Using XPath expressions allows you to make MIPs dynamically change, so that, for example, a form field can be required or not depending on other form fields.

  • Note that MIPs are assigned to XML nodes, not directly to controls. But they affect the controls that are bound to those nodes. This is part of XForms's MVC philosophy.

Single selection controls

XForms is of course not limited to simple input controls. Add the following after the second <xf:input> control:

<xf:select1 ref="language">
    <xf:label>Language</xf:label>
    <xf:item>
        <xf:label>Choose one...</xf:label>
        <xf:value/>
    </xf:item>
    <xf:item>
        <xf:label>English</xf:label>
        <xf:value>en</xf:value>
    </xf:item>
    <xf:item>
        <xf:label>French</xf:label>
        <xf:value>fr</xf:value>
    </xf:item>
    <xf:item>
        <xf:label>Spanish</xf:label>
        <xf:value>es</xf:value>
    </xf:item>
</xf:select1>

Reload the page. You should see the following:

You have just added a single selection control with <xf:select1>. The name means that the user can "select one" item among several items. (XForms tends to call controls using more abstract terms, rather than giving them names such as "combo box" or "menu".) The single selection control usually appears like a drop-down menu or combo box with most XForms implementations (but you can change it's appearance as shown later).

Nested within the control, you find several <xf:item> elements. Each one creates an item in the drop-down menu. An item has two sides: the <xf:label> element specifies the label that is presented to the user, and the <xf:value> element specifies the value that is stored into the XForms instance when the user selects that particular item.

Now XForms encourages you to store data in the model. For a selection control, this means storing the list of labels and values in an XForms instance instead of statically listing the items under the <xf:select1> element. So let's do this! Create a new instance in the model:

<xf:instance id="languages-instance">
    <languages xmlns="">
        <language>
            <name>English</name>
            <value>en</value>
        </language>
        <language>
            <name>French</name>
            <value>fr</value>
        </language>
        <language>
            <name>Spanish</name>
            <value>es</value>
        </language>
    </languages>
</xf:instance>

Then modify the <xf:select1> element as follows:

<xf:select1 ref="language">
    <xf:label>Language</xf:label>
    <xf:item>
        <xf:label>Choose One...</xf:label>
        <xf:value/>
    </xf:item>
    <xf:itemset ref="instance('languages-instance')/language">
        <xf:label ref="name"/>
        <xf:value ref="value"/>
    </xf:itemset>
</xf:select1>

Notice the new <xf:itemset> element in addition to the <xf:item> previously used. That element specifies an item set, which allows you to point to the list of <language> nodes in the languages-instance instance, and for each of those to tell the control where to find the label and the value.

You often don't have to use an item set, but using them gives you the flexibility of reusing existing sets of data, dynamically changing the list of items, easing localization, etc.

Adding a text area

Now add yet another control, a text area:

<xf:textarea ref="notes" appearance="xxf:autosize">
    <xf:label>Notes</xf:label>
</xf:textarea>

The <xf:textarea> element acts very much like the HTML textarea element. It makes sense to use it to allow entering more than one line of text.

Here there is a little trick: you use the appearance attribute to tell Orbeon Forms to use a particular appearance for the text area control. Instead of the standard text area, appearance="xxf:autosize" allows the text area to grow vertically as the user enters more text. (This is an appearance which is specific to Orbeon Forms, and you can tell that because of the xxf: prefix in the appearance value.)

Note that the application captures the same data without the appearance attribute, it's just that the control appears slightly differently and the user experience is changed.

Finishing-up the controls

To create the ratings input, add this new instance:

<xf:instance id="ratings-instance">
    <ratings xmlns="">
        <rating>
            <name>1</name>
            <value>1</value>
        </rating>
        <rating>
            <name>2</name>
            <value>2</value>
        </rating>
        <rating>
            <name>3</name>
            <value>3</value>
        </rating>
        <rating>
            <name>4</name>
            <value>4</value>
        </rating>
        <rating>
            <name>5</name>
            <value>5</value>
        </rating>
    </ratings>
</xf:instance>

And then add another <xf:select1> control:

<xf:select1 ref="rating" appearance="full">
    <xf:label>Rating</xf:label>
    <xf:item>
        <xf:label>None</xf:label>
        <xf:value/>
    </xf:item>
    <xf:itemset ref="instance('ratings-instance')/rating">
        <xf:label ref="name"/>
        <xf:value ref="value"/>
    </xf:itemset>
</xf:select1>

Here again, you store the list of items as a separate instance, but we keep the "empty" item as an <xf:item>. There is something new: the use of the full appearance, which displays the selection control as a list of radio buttons. This is a standard XForms appearance value, which is likely to be supported by all XForms implementations. (You can tell that it is standard because there is no colon : in the appearance value.)

The only missing control now is the input field bound to the <link> element. Add this, and you should have something like this in your controls:

<xf:group ref="book">
    <xf:input ref="title">
        <xf:label>Title</xf:label>
    </xf:input>
    <br/>
    <xf:input ref="author">
        <xf:label>Author</xf:label>
    </xf:input>
    <br/>
    <xf:select1 ref="language">
        <xf:label>Language</xf:label>
        <xf:item>
            <xf:label>Choose One...</xf:label>
            <xf:value/>
        </xf:item>
        <xf:itemset ref="instance('languages-instance')/language">
            <xf:label ref="name"/>
            <xf:value ref="value"/>
        </xf:itemset>
    </xf:select1>
    <br/>
    <xf:input ref="link">
        <xf:label>Link</xf:label>
    </xf:input>
    <br/>
    <xf:select1 ref="rating" appearance="full">
        <xf:label>Rating</xf:label>
        <xf:item>
            <xf:label>None</xf:label>
            <xf:value/>
        </xf:item>
        <xf:itemset ref="instance('ratings-instance')/rating">
            <xf:label ref="name"/>
            <xf:value ref="value"/>
        </xf:itemset>
    </xf:select1>
    <br/>
    <xf:textarea ref="notes" appearance="xxf:autosize">
        <xf:label>Notes</xf:label>
    </xf:textarea>
</xf:group>

And this is how the result should look like (you will see how to add the Save button you see on this screenshot in the next section):

By now you probably get the gist of it!

PreviousThe Bookcast applicationNextDatabase access

After having looked at the , this should be clear, with a little novelty: <xf:group>. This element allows grouping XForms controls together. The ref="book" element changes the current evaluation context for the nested controls, which means that they can use simpler XPath expressions: ref="title" instead of ref="book/title" and ref="author" instead of ref="book/author" (groups have other uses but you don't need to learn that now).

The <xf:bind> element is used to assign so-called (or MIPs) to XForms instance nodes (typically XML elements or attributes). Such properties include whether a field is required, read-only, or visible; whether the field has to satisfy a certain constraint or be of a particular type; and whether the field is a calculated value.

view.xhtml
page-flow.xml
Hello example
Model Item Properties