Form Design

The purpose of this document is to provide a detailed breakdown of XForms, specifically the subset of XForms implemented by JavaRosa, so that anyone can make their own. As of this writing there are several tools to help create your own XForms that work on JavaRosa platforms. They all allow you to create XForms, though generally the easier they are to use the less advanced functionality they provide. This set of pages will hopefully allow you to manually edit forms to your specific needs.

Begin with a Javarosa-compliant Automated Design Tool

Use an automated tool compatible with javarosa to build the basic Xform. These tools understand the text internationalization features of javarosa Xforms and can restructure your input so that the question text is grouped into an <itext/> translation block for internationalization.

We have a form design guide, the JavaRosa community has a description of the specification we support and a good tutorial. We also have examples of forms available. We have a simple graphical form designer ODK Build. Another form builder XLSForm uses an Excel spreadsheet of questions to generate the Xform file; it is more suitable when working with larger forms. PurcForms designer is another tool.

Our experience is that these form design tools can provide a good starting point, but, to enable advanced features, you will inevitably need to edit the resulting form. After hand-editing, you should verify the syntax of the form using ODK Validate.

Overview of an XForm File

XForms consist of three major components:

  1. The instance -- where your data is going to be stored. For each prompt, you need a place to store your answer.
  2. The bindings -- For each instance variable, you can include information about that data like the type (string, integer, etc..), the constraints on that data (i.e. less than 3), whether it’s required or not, etc....
  3. The body -- How prompts are displayed to the user.
<h:html xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jr="http://openrosa.org/javarosa">

<h:head>
  <h:title>Simple Form</h:title>
  <model>

  <!-- instance -->
  <instance>
   <data>
     <mystring/>
   </data>
  </instance>

  <!-- bindings -->
  <bind nodeset="/data/mystring" type="string"/>

  </model>
</h:head>

<!-- body -->
<h:body>
  <input ref="mystring">
    <label>This is a string prompt</label>
    <hint>You don't need a hint, but you can add one</hint>
  </input>
</h:body>

</h:html>

Instance

Let's start with the instance:

<instance>
  <data>
    <mystring/>
  </data>
</instance>

In this example we have a single instance called "data" (which could be called anything, really) and that instance has a single variable called "mystring." Note that </mystring> is where we're going to store the answer to our prompt, but it's only a placeholder. We do _NOT_ specify a data type here.

An instance also represents a saved or completed version of the form. When you are done, the output will look like this:

<instance>
  <data>
    <mystring>Hello World!  This is my answer!</mystring>
  </data>
</instance>

Similarly, if you populate <mystring> in the original xform, it fills that in as the default answer to a prompt:

  <mystring>Default answer</mystring>

Adding more prompts is as simple as adding more variables:

<instance>
  <data>
    <mystring/>
    <a_number/>
    <birthday/>
    <date>2010-06-15</date>
    <select>a c</select>
    <favorite_number>7</favorite_number>
    <whatever_i_want/>
  </data>
</instance>

Variable names can be anything you want. The only caveat is that they must not contain spaces
<my_variable/> is legal.
<my variable/> is not.

Bindings

Since we only have one prompt element, we only have one binding:

  <bind nodeset="/data/mystring" type="string"/>

This binding only specifies that this data type is a string. Bindings not including a "type" are assumed to be strings. The binding is also where you specify branching, required, input constraints, etc.

Note that the binding references the instance node using an XPath expression. The expression represents the hierarchy inside the <instance> tags.

<instance>
  <data>
    <mystring/> <!-- referenced as /data/mystring -->
  </data>
</instance>

In this example, mystring is represented as: /data/mystring.

Body

The body represents what should be shown to the user. In this example, since we only have one prompt, we only have one body element.

<h:body>
  <input ref="mystring">
    <label>This is a string prompt</string>
    <hint>You don't need a hint, but you can add one</hint>
  </input>
</h:body>

The type of widget/prompt to show the user is specified by the <input> tag. Where to put the data is specified by the ref="" attribute. The <label> is what will be shown to the user as the prompt header, and the <hint> is an optional piece of text to display.

For a full list of body element types see form body or look through the widget examples.

Adding another prompt

To finish our example, we'll add another prompt to our form. We'll need to add a new element to the instance, a new binding, and a new element to the body. This time, however, we'll make the prompt required for the user to answer. Lines added are in red.

so our new form now looks like this:

<h:html xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jr="http://openrosa.org/javarosa">

<h:head>
  <h:title>Simple Form</h:title>
  <model>

    <instance>
      <data>
        <mystring/>
        <q2/>
      </data>
    </instance>

    <bind nodeset="/data/mystring"/>
    <bind nodeset="/data/q2" required="true()"/>

  </model>
</h:head>

<h:body>
   <input ref="mystring">
     <label>This is a string prompt</label>
     <hint>You don't need a hint, but you can add one</hint>
   </input>
   <input ref="q2"> <label>This is another prompt</label> <hint>This prompt is required</hint> </input>
</h:body>

Notes