Creating Forms in OpenOffice


Contents

Introduction

As part of the MVC Data Entry Alternatives project, OpenMRS is attempting to replace its current dependency on Microsoft InfoPath for data entry with open-source applications that utilize the XForms specification. One such alternative is OpenOffice.org, an open-source fully-fledged office suite.

This guide will show you how to [re]create the InfoPath forms that OpenMRS currently uses in OpenOffice. Everything in this guide will work on Linux, OS X, and Windows. It is a work in progress and will be constantly evolving.

Requirements

A Quick Description of the Files

FormEntry.xsd

This is the XML schema for all of the necessary patient data. It contains the name, type, and valid values for all of the form elements. We will be using it primarily to extract valid values for form elements. Here is an example of the contents of this file. More explanation will follow later: <pre><xs:complexType name="shortness_of_breath_duration_type">

 <xs:sequence>
   <xs:element minOccurs="0" name="date" nillable="true" type="xs:date"/>
   <xs:element minOccurs="0" name="time" nillable="true" type="xs:time"/>
   <xs:element maxOccurs="1" minOccurs="0" name="value" nillable="1">
     <xs:simpleType>
       <xs:restriction base="xs:string">
         <xs:enumeration value="1073^WEEKS^99DCT"/> <!-- WEEKS -->
         <xs:enumeration value="1074^MONTHS^99DCT"/> <!-- MONTHS -->
         <xs:enumeration value="1072^DAYS^99DCT"/> <!-- DAYS -->
       </xs:restriction>
     </xs:simpleType>
   </xs:element>
 </xs:sequence>
 <xs:attribute fixed="5962^SHORTNESS OF BREATH DURATION^99DCT" name="openmrs_concept" type="xs:string" use="required"/>
 <xs:attribute fixed="CWE" name="openmrs_datatype" type="xs:string" use="required"/>
 <xs:attribute fixed="0" name="multiple" type="xs:integer" use="required"/>

</xs:complexType></pre>

template.xml

This is a mapping of the data entered in the forms to the XML schema. For example, data in the forms gets mapped to the schema above via the following: <pre><shortness_of_breath_duration openmrs_concept="5962^SHORTNESS OF BREATH DURATION^99DCT" openmrs_datatype="CWE" multiple="0"> <date xsi:nil="true"></date> <time xsi:nil="true"></time> <value xsi:nil="true"></value> </shortness_of_breath_duration> </pre> Data entered in the form will be inserted into the <value> tag.

The .xsn Files

These are the files that are opened within InfoPath. They contain FormEntry.xsd, template.xml, and other files that allow the forms to be edited and filled in within InfoPath. Here is a screenshot from the Adult Initial Verification form (15.xsn in the above archive):

OpenOffice and XForms

Recent versions of OpenOffice allow you to create and use XForms documents via the XML Forms component of Writer. You can import an XML schema, create a new schema from within the document, create form elements in a WYSIWYG editor, bind the elements to the schema, bind the schema to a database, submit the form to a remote URL, database, or local file, and add custom scripting to the form via macros. Most of InfoPath's core behavior is replicated in OpenOffice, but some things are missing (notably, the taskpane which can view remote HTML, and the ability to automatically load in pre-filled templates). Overall, the process of creating forms is slightly more manual in OpenOffice than it is in InfoPath, but this isn't a significant limitation.

Creating a Form

We should have everything we need to create a form in OpenOffice now. We will be creating the first section of the screenshot shown in The .xsn Files. This will allow us to work with several different form controls and we should have an understanding of all of the steps involved to create complete forms. You may wish to open 15.xsn from the xsns archive linked previously in InfoPath now, or just work from the screenshot provided.

Create a new XML Forms document

  1. Launch OpenOffice Writer and create a new XForms document via File | New | XML Form Document
  2. You should have a blank document with a floating window titled "Form Controls". Bring up the "More Controls" window by clicking the "More Controls" button on the "Form Controls" window:
    Image:morecontrols.png

  3. We'll need the "Ungroup" button added to our toolbar for use later, so add it by clicking the arrow at the bottom of the window:




Importing the Template

  1. In the "Instance 1" tab of the Data Navigator on the right, click the "Instances" button at the bottom and select "Add":
    Image:Addinstance.png

  2. Give the instance data a meaningful name: we'll call this one "Initial Visit". Under URL, select your local copy of template.xml or enter http://pics.discosoup.net/OpenMRS/template.xml [TODO: change this URL]. Be sure the "Link Instance" button is NOT checked.
    Image:Instancename.png

    You should now see a new tab called "Initial Visit". This contains the imported template.xml which is now stored inside the document itself.
  3. Delete the old "Instance 1" by clicking its tab, then click the "Instances" button and selecting "Remove":
    Image:Deleteinstance.png

  4. Inspect the XML tree in the "Initial Visit" tab by clicking the + next to "<form>":
    Image:Xmltree.png

    Now we should have everything we need to start adding content.

Create a Table

In order to put form controls into the document, we'll be putting everything into tables.

  1. Create a table of 1 row and 2 columns for the header and date. Go to Insert | Table and enter the following (name is optional):
    Image:Insertable.png

  2. In the first cell, enter the title of the forum as "AMPATH: Adult Initial Encounter Form". Click B in the formatting toolbar at the top to make this bold. You can also change the background color by clicking the "Background Color" button in the Table toolbar:
    Image:Backgroundcolor.png

Add Form Controls

  1. Now we can add our first bit of data, a Date field. In the Data Navigator, expand "encounter" and locate "encounter.encounter_datetime". This is called a node or element. Drag this element over to the document window and into the second table cell:
    Image:Datedrag.png

    This does two things: first, it adds a Labelfield and Textbox grouped together to the document. Second, it creates a binding to the element "encounter.encounter_datetime" and binds this control to it.
  2. Now we need to format the controls and replace the Textbox with a DateField. With the form controls you just made still selected, click the "Ungroup" button we added earlier, or go to Format | Group | Ungroup:
    Image:Ungroup.png

  3. Select the Labelfield and double-click it to bring up its Properties window. Change its label to "Date:", select a font(see a note on fonts below), and drag the green arrows to resize the control to make it smaller, leaving some space after the text:
    Image:Datelabel.png

    A Note on Fonts: Choosing a font that looks well cross-platform is difficult since different platforms will render them at different sizes. Times New Roman 9 pt seems to be a good font and size for these labels, but they will appear differently on multiple platforms. For more on this subject, see here and here.
  4. Drag the label around and place it where you want it. You may find it helpful to turn on "Guides when Moving" and "Snap to Grid" on the toolbar next to the Ungroup button. You may also want to change the anchoring via right-clicking the control | Anchor.
  5. Since this is supposed to be a DateField, we want to replace the Textbox with a way to select the date. Right click on the Textbox, and select Replace with | Date Field:
    Image:Datefield.png

  6. This gives us a field with the date 01/01/1900. We can make this a calendar by double clicking it to bring up the Properties window and setting the following values:
    Image:Dateproperties.png

  7. Drag the DateField around to put it into position the same way you did with the label. Resize the table and adjust the controls as necessary to achieve the desired look.

Editing the Bindings

  1. Click on the "Bindings" tab in the Data Navigator and notice there is one entry there, "Binding 1: encounter/encounter.encounter_datime". This is a binding called Binding 1 with the XPath value of encounter/encounter.encounter_datetime.
  2. "Binding 1" isn't a descriptive name, so select the binding and click the "Edit" button:
    Image:Editbinding.png