We recommend using Tomcat for this tutorial, but Orbeon Forms can deploy into containers other than Tomcat.
Orbeon Forms Tutorial
- 1. What is this?
- 2. A Little Bit of Background
- 3. Installing and Configuring Orbeon Forms
- 4. The Hello Application
- 5. The Bookcast Application
- 5.1. What is it?
- 5.2. Getting Started
- 5.3. XForms Model and Instance
- 5.4. First Controls
- 5.5. Adding Constraints
- 5.6. Single Selection Controls
- 5.7. Adding a Text Area
- 5.8. Finishing-Up the Controls
- 5.9. Adding a "Save" Button
- 5.10. Loading the Initial Data
- 5.11. Adding More Books
- 5.12. Deleting a Book
- 5.13. Adding a "Revert" Button
- 5.14. Making Things Look Nicer
- 5.15. Adding Validation
- 5.16. The Atom Feed
- 6. What's Next
1. What is this?
This is the tutorial for Orbeon Forms version 3.6.
If you have questions, issues or suggestions related to this tutorial, please send a message to the
ops-users mailing-list. It is easy to subscribe by following the instructions at http://www.orbeon.com/forms/mailing-list.
2. A Little Bit of Background
2.1. What Orbeon Forms Does for You
Orbeon Forms is an open source solution to build and deploy web forms. For more information, please visit the Orbeon home page at http://www.orbeon.com/.
2.2. Prerequisites
To go through this tutorial, you don't need much: any reasonably modern computer on which you can install Java 1.5 or 1.6 should do (Java 1.4.2 may work for you but 1.5 or 1.6 is strongly recommended). You should be comfortable with installing new software on your computer, including uncompressing zip or gzip archives. You will also have to edit XML files. If you are familiar with HTML, this should not be a problem.
You also need a reasonably recent web browser. We recommend one of the following browsers:
-
Mozilla Firefox 1.5 or 2 or greater.
-
Safari 2 or greater.
-
Opera 9 or greater.
-
Internet Explorer 6 or 7 or greater.
You will not have to:
-
Write any Java code or any scripting language code.
-
Use a compiler or other complicated build tool.
-
Install browser plugins or any other client-side software, besides your regular web browser!
2.3. Principles of Orbeon Forms
Orbeon Forms follows a few principles:
-
More standards. You use standards whenever possible. For example, Orbeon Forms applications are created using XForms and XHTML, which are W3C standards.
-
Less scripting. You write most applications without writing Java, JavaScript, or other scripting code. (But you can if you really want.)
-
Instant gratification. You get instant gratification by making changes to your application and just reloading your page in your web browser. (You don't need to "compile" or "build".)
3. Installing and Configuring Orbeon Forms
3.1. Downloading and Installing Java
Java provides the cross-platform environment in which Orbeon Forms runs.
If you don't have Java installed yet, download it from the Sun web site at http://java.sun.com/javase/downloads/index.jsp. Sun provides Windows, Linux and Solaris versions. If you use a Mac with Mac OS X, you probably have Java already installed on your machine, but if not visit http://www.apple.com/macosx/features/java/. Then follow the instructions to install Java.
3.2. Downloading and Installing Apache Tomcat
Tomcat is the container application into which Orbeon Forms deploys. Follow these steps to download and install Tomcat if you don't have it installed yet:
-
Download Tomcat 5.5 from the Apache web site at http://tomcat.apache.org/download-55.cgi.
-
Install Tomcat as per the instructions. If you downloaded the installer version (Windows only), run the installer. If you downloaded a compressed archive, uncompress it to the location of your choice. We call the install location
TOMCAT_HOME(on windows, this could bec:/Program Files/Apache/Tomcat, on a Unix system,/home/jdoe/tomcat, etc.). -
Check that your Tomcat installation is working correctly:
-
Run the Tomcat startup script under
TOMCAT_HOME/bin(startup.shorstartup.batdepending on your platform), or start Tomcat with the control application (Windows only). -
Open a web browser and access the following URL:
http://localhost:8080/You should see the Tomcat welcome page.

-
3.3. Downloading and Installing Orbeon Forms
Follow these steps to download and install Orbeon Forms:
-
Download Orbeon Forms 3.6 or later from http://www.orbeon.com/forms/download.
-
Uncompress the archive into a directory of your choice. We call that directory
ORBEON_FORMS_HOME. -
Under
ORBEON_FORMS_HOME, you find a file calledorbeon.war. This is the file to deploy into Tomcat. To do so, just copy it underTOMCAT_HOME/webapps(alternatively, if you know what you are doing, you can uncompress it at a location of your choice and configure a context inTOMCAT_HOME/conf/server.xml). Thewebappsdirectory is already present after you have installed Tomcat.
3.4. Testing your setup
Make sure you restart Tomcat (run the shutdown script under TOMCAT_HOME/bin, and then
the startup script again). Then open up with a web browser the following URL:
You should see the Orbeon Forms welcome page:

You can now navigate the list of sample applications listed on the left side. You can see the source code of each application directly in your web browser by selecting the "View Source Code" tab at the top of the page to open up the Orbeon Forms Source Viewer:

4. The Hello Application
4.1. Running the Hello Application
The Hello application is about the simplest Orbeon Forms application you can think of. It asks for your name and displays it back. You run the Hello application by selecting the link "XForms Hello" in the list of applications. Here are direct links for running XForms Hello on your local Orbeon Forms install or online on the Orbeon web site.
Simply enter your first name in the input field, for example "Joe". You should promptly see a message underneath saying "Hello, Joe!".

You can directly view the source code from your web browser by selecting the "View Source Code" tab. There you see:

-
view.xhtml: this is the XHTML and XForms code for the Hello application. -
page-flow.xml: this is the page flow for the Hello application. The main task of a page flow is mapping external URLs (as typed in a web browser) to Orbeon Forms pages.
4.2. The Source Code
You are now ready to look at the source code of the Hello application. This will give you an idea of
what an Orbeon Forms application looks like. First, select view.xhtml to make the
source code for that file appear on the right:
The first thing you notice is that this looks very much like HTML (notice the <html>
tag). But in fact, this is XHTML, the XML-compatible version of HTML. There are only a few
differences that matter between HTML and XHTML, in particular you must close all your tags and use
quotes around attributes. Also, you must place your tags in a namespace, which is why the
<html> tag features the xmlns="http://www.w3.org/1999/xhtml"
namespace declaration.
Another difference with plain HTML is that there are tags that start with the string
xforms:. Those are defined by the XForms
specification from W3C. They are at the heart of Orbeon Forms and enable all the cool forms
features that you see in Orbeon Forms demos. (In order to use XForms tags that start with
xforms:, you must add another namespace declaration on the <html> tag:
xmlns:xforms="http://www.w3.org/2002/xforms".)
Using XForms in Orbeon Forms means that you don't have to use HTML forms at all. The benefit is that XForms is much more powerful than HTML forms, as you will see in this tutorial.
You notice a tag called <xforms:model>. Because XForms follows a
Model-View-Controller (MVC) approach, most XForms pages contain one or more models that
usually encapsulate other XForms markup. You place these models under the XHTML
<head> tag.
Note that from now on, we prefer the term element to the term tag. An element is an XML term that includes the start tag and end tag, and can have content such as other elements and text.
With XForms, you store the data captured by controls such as input fields, combo boxes, etc. as text
contained within XML elements or attributes. Consider the following XML document containing a
single element called first-name.
The first-name element is empty. Contrast with:
The element now contains the string "Joe". Notice how in view.xhtml the XML document
is encapsulated within an <xforms:instance> element:
Also notice the special xmlns="" namespace attribute on <first-name>:
this is necessary because the root element of the XHTML document defines a default namespace with
xmlns="http://www.w3.org/1999/xhtml". Because we want to make it clear that the element
<first-name> is not an XHTML element, but an element in no namespace, we add
xmlns="" to that element. If your instance document must be in no particular namespace,
you are always safe to add xmlns="" on the root element of that instance.
This element defines an XForms instance, which is just XForms' way of calling an XML document used to store data.
Now consider the remaining XForms elements in the source file: <xforms:input> and
<xforms:output>. These two elements are not located under the XHTML
<head>, but under <body>. They are part of the view of your
page, in other words these elements directly help define visible controls on the page. Consider
<xforms:input>:
You guessed that this element allows the user to input information.
<xforms:input> is usually displayed to the user as an input field. The
ref attribute is the magic that connects the input field to the XForms instance. It
contains an XPath expression, which in this case just looks like a file path. In this case,
/first-name points to the element called first-name, which happens to be
the only element we have in the XForms instance. Using the ref attribute this way is
called a binding and means two things:
-
When the user enters text in the input field, the text is saved into the element called
first-name. -
It also goes the other way: if somehow the text content of
first-namein the XForms instance changes, this is automatically reflected in the input field.
Now consider <xforms:output>. As you guess from the name of the element, this simply
displays a value on screen. If you have tried running the Hello application, you have probably
guessed the logic that is being implemented: if the first name entered by the user is not a blank
string, then we display the "Hello" message followed by the first name and then an exclamation mark.
Otherwise if the first name consists only of spaces, we just display a blank string. The idea is to
avoid displaying things like "Hello !" without an actual first name.
With many client-side libraries, you express this type of logic with JavaScript. With XForms, you use XPath instead. This means that you need to learn at least a few bits of the XPath syntax. While XPath may be different from what you already know (it is based on expressions and definitely targeted at XML), it is in fact a smaller language than JavaScript.
So how do you hook-up the logic within <xforms:output>? Here, instead of a
ref attribute, we use a value attribute. Like ref,
value takes an XPath expression, but it doesn't actually create a binding to instance
data: it just returns a string. The XPath is as follows:
A few things to point out:
-
The main expression has the form
if () then ... else .... (This is actually an XPath 2.0 expression, which supports theifconstruct.) -
The
normalize-space()function removes all leading and trailing space (and simplifies internal spaces as well). This is a little trick to not only test whether the first name is empty, but also to test whether it is an all-blank string. -
Contrary to JavaScript, the equality test is expressed with a single
=instead of==. -
The
concatfunction concatenates all its parameters into a resulting string. It is like the JavaScript+operator on strings. -
Note the use of the single quote
'around strings. This is needed because the XPath expression is put within double quotes"in thevalueattribute.
4.3. Page Flow
If you look at your browser's URL bar when showing the example, you notice that it looks like this:
-
The first part of the URL,
http://localhost:8080/, is self-explanatory: it depends on what host and port your server is running. -
The next part,
orbeon, depends on what context you install Orbeon Forms into. By default, because the WAR file is calledorbeon.war, the context isorbeon. (You could as well configure your container to use a different context, or an empty (default) context.) -
The last part,
/xforms-hello/, automatically matches the name of the directory you store your application into (more on this later when you look at the source code). This causes the application's page flow (page-flow.xml) to run.
So now look at page-flow.xml for the Hello application. It is very simple:
The important line in this page flow is this one:
It tells Orbeon Forms that any path (notice the wildcard *) sent by the web browser to
this application causes the page view stored in view.xhtml to be processed. You can
check this by entering the following path in your browser:
The exact same result shows! Of course, page flows make the most sense when you have more than one
page in your application, which translates into more than one <page> element.
4.4. Orbeon Forms Resources
Under TOMCAT_HOME/webapps/orbeon, you find a WEB-INF directory. That
directory, in turn, contains a resources directory. We refer to that
resources directory as RESOURCES below.
The RESOURCES directory is very important: this is where your application lives.
This directory is called "resources" because it contains all the files (or resources) such as XHTML
documents, XML schemas, images, CSS, etc. needed by your Orbeon Forms application.
WEB-INF/resources so you can get up
and running without configuration.
4.5. A Look Into the Resources Directory Structure
Under RESOURCES, you see the following files and directories:
-
appsdirectory: contains one sub-directory for each application currently running in Orbeon Forms. By default, it contains a series of sample applications - the ones that you see on the left side of your screen when you start Orbeon Forms. Notice a directory calledxforms-hello: this is the directory that contains the Hello application. -
configdirectory: contains several configuration files that you can modify if needed. For now, you don't need to worry about this directory. -
page-flow.xmlfile: the top-level page flow file. You should not worry about this file just yet. Just know that by default, it is in charge of deciding which application to run depending on the application name in the URL that you enter in your web browser. -
apps-list.xmlfile: contains the list of sample applications to display on the left side of the screen. This is not needed by your own application.
4.6. Playing with the Hello Application Source Code
You find the application under RESOURCES/apps/xforms-hello. That directory contains
the two files that you have seen earlier through the Source Code Viewer in your web browser. Again,
the name xforms-hello is important and matches the xforms-hello part of
the URL in your web browser: http://localhost:8080/orbeon/xforms-hello/.
In this tutorial, you will often have to "reload" pages in your web browser to see the effects of your changes to XHTML or XForms markup. Because of the way Orbeon Forms handles page reloads with XForms, for consistent results we recommend that you don't simply use your browser's reload button, but instead use one of the following two ways to reload a page:
-
Position your text cursor on your browser's URL bar and press the "Enter" key. Browsers often have keyboard shortcuts such as
CTRL-LorCMD-Lto reach the URL bar. -
Use your browser's "force reload" feature. This is often enabled by pressing the
SHIFTkey and pressing the "reload" button at the same time. Browsers often have keyboard shortcuts such asCTRL-F5,CTRL-SHIFT-R, orCMD-SHIFT-Rto perform this operation.
Now, modify view.xhtml:
-
Open
view.xhtmlin a text editor. -
Modify the string "Please enter your first name:" with "Your name here:".
-
Save
view.xhtml. -
Go back to the Hello application in your web browser and reload the page. You should see the new text appear:

-
Repeat the experience but add some XForms. For example, add a second
<xforms:input>right after the first one:<xforms:input ref="/first-name" incremental="true"/><xforms:input ref="/first-name" incremental="true"/>Reload the page, and notice, as you type in an input field, how the other one updates as you type. This happens because the two fields are bound to the same instance data. The
incremental="true"attribute allows the changes to occur as you type, instead of occurring when you focus in and out of fields:
You notice that you get instant gratification with Orbeon forms: just change files on disk, reload your page, and your changes are taken into account with no compilation or other complex deployment.
5. The Bookcast Application
5.1. What is it?
In this section, you will create a more complete XForms application: the Bookcast application. The Bookcast application allows you to keep track of information about books you have read. For each book, you enter information such as title, author, language, and your own comments. The information is persisted so you can access it again. Then you can do cool things with the available data such create an Atom feed of your entries.

You can run the final application on your local Orbeon Forms install or online on the Orbeon web site.
5.2. 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-bookcastapplication, so instead let's decide on another name, for examplemy-bookcast. Create a directory with that name asRESOURCES/apps/my-bookcast. For convenience, we refer to that new directory as theBOOKCASTdirectory below. -
Create a
page-flow.xmlfile underBOOKCAST:<config xmlns="http://www.orbeon.com/oxf/controller"><page path-info="/my-bookcast/" view="view.xhtml"/><epilogue url="oxf:/config/epilogue.xpl"/></config>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 calledview.xhtml. -
Create a skeleton for your
view.xhtmlunderBOOKCAST:<html xmlns:xxforms="http://orbeon.org/oxf/xml/xforms" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/1999/xhtml"><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:
You should something like this:

If you get lost at some point in this tutorial, feel free to look at the reference source files for the bookcast application:
5.3. 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):
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 <xforms:model> element:
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!
5.4. First Controls
Now it's time to add some visual controls to your page. Start with the following under the
<body> element:
Reload the page. You should seem something like this:

After having looked at the Hello example, this should be clear, with a little novelty:
<xforms: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).
Another thing: all XForms controls require a nested <xforms: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
(<xforms:label/>).
5.5. Adding Constraints
Now say you want to make the title and author required data. You control this with the
<xforms:bind> element in the XForms model. Add the following under
<xforms:model> after your instance:
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:
-
The
<xforms:bind>element is used to assign so-called Model Item Properties (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. -
Here we use the
requiredattribute, which determines whether a field is, well, required, that is, whether it has to be filled out by the user. -
Much like
<xforms:group>in the controls,<xforms:bind>elements can be nested. -
<xforms:bind>doesn't use arefattribute to point to instance nodes, but anodesetattribute, which allows pointing at more than one node using a single XPath expression. -
The outer
<xforms: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<xforms:bind>element is the root element of the first XForms instance. You could be more explicit, for example with:<xforms:bind nodeset="/books/book">...</xforms:bind>Or with:
<xforms:bind nodeset="instance('books-instance')/book">...</xforms:bind>The latter makes it clear, with the XForms
instance()function, that you are addressing thebooks-instanceinstance and not another instance, so you will probably tend to prefer that notation. -
The inner
<xforms:bind>elements apply the required MIP to the<title>and<author>elements. Therequiredattribute must contain an XPath expression, which is why it containstrue()(the way to express a Boolean "true" value in XPath) and not simplytrue. 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.
5.6. Single Selection Controls
XForms is of course not limited to simple input controls. Add the following after the second
<xforms:input> control:
Reload the page. You should see the following:

You have just added a single selection control with <xforms: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 <xforms:item> elements. Each one
creates an item in the drop-down menu. An item has to sides: the <xforms:label>
element specifies the label that is presented to the user, and the
<xforms: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 <xforms:select1> element. So let's do this! Create a new instance in the model:
Then modify the <xforms:select1> element as follows:
Notice the new <xforms:itemset> element in addition to the
<xforms: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.
5.7. Adding a Text Area
Now add yet another control, a text area:
The <xforms: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="xxforms: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 xxforms: 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.
5.8. Finishing-Up the Controls
To create the ratings input, add this new instance:
And then add another <xforms:select1> control:
Here again, you store the list of items as a separate instance, but we keep the "empty" item as an
<xforms: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:
And this is how the result should look like:

By now you probably get the gist of it!
5.9. Adding a "Save" Button
The Bookcast application now allows you to capture some data. But it is not a very useful application yet, because it doesn't do anything with it! So let's see how you can add a "Save" button that, once pressed, well, saves the data in your form.
Many applications use relational databases as a persistence layer. But because Orbeon Forms and XForms use XML as their native data format, it is very appropriate to use a database that understands XML instead. Orbeon Forms comes with the open source eXist database that does just that.
So how do you save data from XForms to a database? An important feature of XForms is the XForms submission. A submission allows you to read and write XML documents using HTTP and other protocols. Because the eXist database has a REST API (in other words an HTTP-friendly interface), XForms can directly talk to eXist to read and writ