XRX/Selection List Generator

< XRX

Motivation

edit

You want to store all your code tables in a central location and have each form dynamically generate selection lists from these code tables.

Method

edit

We will create a very simple XML file format to store all our codes. We will store one code table per file and then write a simple XQuery that goes through all these files to build a sample selection list. This selection list will create an instance in the model to hold each selection list value. It will also populate the instance with the first value in the list.

In our sample, we will assume an XRX file naming standard such as /db/apps/app-name/code-tables/my-code-table.xml where each application contains its own code tables for maximum application portability between systems. Applications that share code tables can store these in a location such as /db/shared/code-tables/my-code-table.xml

Sample Screen Image

edit
 
Output from Selection List Generator

XML File Format

edit
<code-table>
    <code-table-name>PublishStatusCode</code-table-name>
    <definition>A way to classify the publishing workflow of an item.</definition>
    <items>
        <item>
            <label>Draft</label>
            <value>draft</value>
        </item>
        <item>
            <label>Under Review</label>
            <value>under-review</value>
        </item>
        <item>
            <label>Published</label>
            <value>published</value>
        </item>
    </items>
</code-table>

Sample XQuery

edit

This query goes through all the files in the XRX application code-tables collection and looks for XML files that have code-table as the root element. It then creates a report that contains all the selection lists inside a working XForms application.

xquery version "1.0";
import module namespace style ='http://code.google.com/p/xrx/style' at '/db/xrx/modules/style.xqm';
declare namespace xhtml="http://www.w3.org/1999/xhtml";

(: XQuery to construct an XForm for either a new item or update item :)
declare option exist:serialize "method=xhtml media-type=application/xhtml+xml indent=yes"; 

let $app-collection := style:app-base-uri()
let $code-table-collection := concat($app-collection, '/code-tables')
let $code-tables := collection($code-table-collection)/code-table

return
<html xmlns="http://www.w3.org/1999/xhtml" 
xmlns:xf="http://www.w3.org/2002/xforms" 
xmlns:ev="http://www.w3.org/2001/xml-events">
   <head>
      <title>XForms Selection List Tester</title>
      {style:import-css()}
      <link type="text/css" rel="stylesheet" href="block-form.css"/>
      <xf:model>
         <!-- This instance holds the value of each code -->
         <xf:instance xmlns="" id="save-data" src="">
            <data>
               {for $code-table in $code-tables
                 return
                    element {$code-table/code-table-name/text()} {$code-table/items/item[1]/value/text()}}
            </data>
         </xf:instance>
      </xf:model>
   </head>
   <body>
      {style:header()}
      {style:breadcrumb()}
      <h1>Sample with a Model in the XForm</h1>
      {for $code-table in $code-tables
         let $code-table-name := $code-table/*:code-table-name/text()
      return
         <xf:select1 ref="{$code-table-name}">
            <xf:label>{$code-table-name}: </xf:label>
            {for $item in $code-table/*:items/*:item
              return
                 <xf:item>
                    <xf:label>{$item/*:label/text()}</xf:label>
                    <xf:value>{$item/*:value/text()}</xf:value>
                 </xf:item>}
            <xf:hint>{$code-table/*:definition/text()}</xf:hint>
         </xf:select1>
      }
      {style:footer()}
   </body>
</html>

Note that this XQuery uses element constructors to create element names in the instance. It also uses the *:name notation to put data from the null namespace directly into the XForms namespace.

This file also puts the definition of the element directly into the hits of the XForms application. Under some XForms applications such as Firefox the hint appears in a floating ephemeral mode display in the left margin of the form.

Sample CSS File

edit

Here is the block-form.css file that can be used to make each selection appear on a separate line:

@namespace xf url("http://www.w3.org/2002/xforms");
body {font-family: Arial, Helvetica; sans-serif;}

/* This line ensures all the separate input controls appear on their own lines */
xf|output, xf|input, xf|select, xf|select1, xf|textarea {display:block; margin:5px 0;}

/* Makes the labels right aligned in a column that floats to the left of the input controls. */
xf|select > xf|label,
xf|select1 > xf|label
{text-align:right; padding-right:10px; width:250px; float:left;}

Back: File Locking Next: Glossary Term Editor