|Table of Contents
Quick Table of Contents
|8 XForms User Interface
8.1 Conditional Constructs For Dynamic User Interfaces
8.2 Repeating Structures
8.2.1 Design Rationale
8.2.2 Special Event Handlers For Element repeat
8.2.4 Design Consequences
8.3 Reusable Form Controls
8.3.1 Creating User Interface Templates
8.3.2 DTD For uiTemplate And useUITemplate
8.4 Layout in XForms
8.4.1 Orientation and Direction
8.4.3 Controlling Automatic Sizing
8.4.4 Preferred, Minimum, and Maximum Sizes
8.4.5 Packing Controls
8.4.7 Inlines and Blocks
8.5 Multiple Sub-forms Or Sub-pages
The XForms User Interface allows the authoring of dynamic user interfaces, i.e., user interfaces that vary based on the current state of the instance data being populated. As an example, portions of a questionnaire pertaining to the user's automobile may become relevant only if the user has answered in the affirmative to the question 'Do you own a car?'. Another use case for such dynamic user interfaces is when the underlying XForms Model contains conditional structures.
|Editorial note: Raman
|Please do not attach semantics to the element name to prejudge the design.
This element contains one or more
case elements. Each
case has an
that is used within event handlers appearing
within the form controls to activate or deactivate
that portion of the user interface created by the markup
contained within that
<switch id="01" default="initial"> <case id="us"> <group> <caption>Please Specify a US Shipping Address.</caption> </group> </case> <case id="uk"> <group > <caption>Please specify a UK shipping address.</caption> </group> </case> <case id="initial"> <group > ... </group> </case> </switch>
The above will result in the portion of the user interface
contained within the default case being
Next, we define an XForms event handler
toggle below for
activating and deactivating different portions of this
<toggle switch="switchID" case="caseID" />
switchidentifies the switch constructor to be affected.
caseidentifies the portion of the
switchconstruct to activate.
In addition to event handler
toggle, event handler
might be used within construct
switch to cycle through
the various contained
The XForms Model allows the definition of repeating structures such as multiple items being purchased within a purchase order. When defining the XForms Model, such higher-level aggregations are constructed out of basic building blocks; similarly, here we define higher-level user interface constructs that build on the form controls defined previously, that can bind to data structures such as lists and collections.
The basic XForms form controls defined so far
permit populating data instances conforming to
These form controls can be aggregated using
group(see 8.4 Layout in XForms) to form higher-level user
interface form controls. As an extension to this, the user interface markup for
repeating structures only adds encapsulation metadata
about the collection being populated, as well as the
necessary controls needed for adding, deleting and
navigating the items in the repeating structure.
Finally, this section also defines relevant portions of the
processing model that track the item that is
current in a repeat structure..
repeat encapsulates the following
pieces of metadata:
Binding expression specifying the collection to be
populated by the contained XForms form
This binding expression returns a node-set that
represents the collection of items over which
repeat will iterate.
Starting index of the first element from the collection to be displayed to the user.
Number of elements from the collection to be displayed to the user.
We define XForms-specific event handlers for
use within element
These event handlers will appear within element
onevent to specify the event handler to
trigger when an event is received by the containing
In the examples below, we will assume event
however, note that this specification does not normatively
define the mapping between physical events
and specific behaviors.
repeat introduces the notion of a
cursor that is maintained by
the XForms processing model for each repeating structure.
repeat has its own
a conceptual cursor.
Event handlers are provided for querying and updating the
position of this cursor;
this cursor position in turn is used for determining the
Thus, these event handlers can be thought of as the markup
equivalent of the additions to the XForms DOM
introduced by construct
setRepeatCursor for marking an item as
<setRepeatCursor repeat="repeatId" cursor="itemID"/>
repeatidentifies the repeat constructor whose cursor is to be updated.
cursoridentifies the cursor position. It should be a binding expression that evaluates to an element of the node set being iterated over by this repeat construct.
getRepeatCursor for accessing
position of the repeat cursor.
<getRepeatCursor repeat="repeatId" />
repeatidentifies the repeat constructor whose cursor position is to be obtained.
for changing item that is current.
<scroll repeat="repeatId" step="n" />
repeatidentifies the repeat constructor whose cursor position is to be updated.
stepis an integer value that specifies the amount by which the list is scrolled. Negative values may be used to scroll the list in the reverse direction.
insert for inserting an item at the current
cursor position into the
repeating structure. This causes the instantiation of
the necessary user interface
for populating a new entry in the underlying collection. It also
updates the instance data by instantiating the necessary
<insert repeat="repeatId" />
repeatidentifies the repeat constructor being affected, and defaults to the
repeatconstruct within which this event handler appears.
delete for deleting an item from the
repeating structure. This causes the destruction of
the necessary user interface for populating the entry
at the current cursor position in the underlying
collection. It also updates the instance data by
destroying the necessary nodes.
<delete repeat="repeatId" />
repeatidentifies the repeat constructor being affected, and defaults to the
repeatconstruct within which this event handler appears.
The event handlers enumerated above may be used within event
listeners attached to
placed inside the body of construct
In combination with the facilities provided by
group and CSS layout, this allows
document authors to customize the positioning of
controls for standard actions such as insert or
repeat represents a repeating homogenous
collection, in other words, a collection consisting
entirely of like form controls.
<repeat ref="bindingExpr" startIndex="si" number="n"> <caption>Shopping Cart</caption> <!-- XForms UI for one element of the collection --> <!-- controls for adding, deleting and navigating entries --> </repeat>
Notice that the underlying schema for the
collection being populated would typically have defined
maxOccurs; these values will in
turn determine if the user agent displays
appropriate UI controls for the user to add or
delete entries in the collection. Event listeners
repeat control UI
aspects such as scrolling and insertion. This
specification will not specify normative means for
displaying such add and delete controls; as with the
rest of the XForms User Interface design, we leave
these to be flexible while showing a default
<repeat (common attributes) startIndex = xsd:positiveInteger : 1 number = xsd:nonNegativeInteger > <!-- caption, help?, hint?, onevent?, ( any form control )* --> </repeat>
common attributes defined in 7.13.1 Common Attributes
startIndex = xsd:positiveInteger : 1 - 1-based hint to the XForms Processor as to which starting element from the collection to display.
number = xsd:nonNegativeInteger - hint to the XForms Processor as to how many elements from the collection to display.
any form control - any form control defined in 7 Form Controls
This subsection enumerates the design consequences and is for members of the Working Group to evaluate the above design.
Binding expression is placed on element
repeat and should refer to the
collection being populated, not to an
individual item of the collection. Thus, it
items/item in a
purchase order, where element
contains one or more
The form controls appearing inside
repeat needs to be suitable for
populating individual items of the collection.
Thus, to continue the purchase order example,
the contained XForms form controls
would need to be suitable for populating a data
instance conforming to
A simple but powerful consequence of the above
is that if the XForms Model specifies nested
collections, then we can create a corresponding
user interface by nesting
repeat elements. As an example,
consider the XForms Model for a hypothetical
purchase order that contains element
items for holding collection of
item elements. Further, assume that
item comprises of two atomic
partNumber and a collection
colors which in turn holds one or more
color elements. The user interface for
populating this data instance would use nested
Notice that the
contained XForms form controls inside
repeat do not explicitly
specify the index of the collection entry being
populated. This is intentional; it keeps both
authoring as well as the processing model
simple. But as a consequence, the user
interface cannot bind to an element from the
underlying collection out of
sequence. Notice that this is not a
serious drawback because the use interface layer
can always populate a specific member of a
collection without using element
User Interface templates allow the creation of reusable user interface components. Just as we can define data types and structures that can be reused within the XForms Model, reusable user interface components allow us to design complex user interfaces using the basic building blocks described in the previous section, and then reuse these components in multiple situations. As with any component framework, this has two basic requirements:
Components need to declare what aspects of the component are parameterizable by the caller.
The caller needs to be able to override the default values of the parameters declared in the component.
Here, we describe such a component framework along with sample markup. For
this example, assume that
USShippingAddress is a reusable data
type that is used in multiple places in the XForms Model, e.g. the user will
be asked for a
<group> <textbox ref="address/street"> <caption>Please enter your street address</caption> </textbox> <textbox ref="address/zip"> <caption>Zip Code</caption> </textbox> </group>
Next, we prepare the above fragment to become a reusable component that could be used for obtaining both the shipping and billing address. To do this, we need to parameterize those portions of the component that the caller will wish to modify.
<uiTemplate id="AddressWidget"> <param name="streetPrompt"/> <param name="zipPrompt"/> <param name="border" value="line"/> <group border="$border"> <textbox ref="address/street"> <caption><value-of name="streetPrompt"/></caption> </textbox> <textbox ref="address/zip"> <caption><value-of name="zipPrompt"/></caption> </textbox> </group> </uiTemplate>
Note that the markup shown above does not create a
user interface; user interface is created by explicitly
instantiating the component via element
useUITemplate described next.
Next, we use this component to instantiate the user interface for obtaining the shipping and billing address.
<useUITemplate ref="myAddress" component="AddressWidget"> <withParam name="streetPrompt">Shipping Street Address</withParam> <withParam name="zipPrompt">Zip Code for shipping state</withParam> <withParam name="border">dotted</withParam> </useUITemplate>
The reusable component is instantiated by element
parameter values are specified by the contained
xform sets the binding context relative to which binding expressions within the instantiated template get evaluated.
TODO: convert to 'XML Representation' consistent with rest of spec.
<!-- param element for use in uiTemplate --> <!ELEMENT param EMPTY> <!-- name Name of parameter being declared --> <!ATTLIST param name CDATA #REQUIRED> <!-- Defines a reusable user interface template --> <!ELEMENT uiTemplate (param*, %FormControls;+)> <!-- id Unique ID for use when instantiating this template --> <!ATTLIST uiTemplate id ID #REQUIRED> <!-- Used to pass parameter values when instantiating uiTemplate --> <!ELEMENT withParam #MIXED> <!-- name Name of parameter whose value is being specified --> <!ATTLIST withParam name CDATA #REQUIRED>
group element is used as a container
for defining a hierarchy of form controls. Groups lay
out their children using a constraint-based system
that supports both relative flexible sizing and
intrinsic sizing. Groups can be nested to create
complex hierarchies. Using CSS, an inline box can be
specified using the
display property with
a value of
inline. A block-level group can
be specified with a value of
is the default.
<group> <!-- all form controls & mixed content --> </group>
controls defined so far are treated as
inline text for purposes of XHTML processing.
XForms visual clients are expected to use a a box layout model as defined by CSS for
determining the overall layout of the XForms visual
interface. Grouping of form controls using
also provides semantics about the relationship amongst user
interface controls; such knowledge can be useful in
delivering a coherent UI to small devices--e.g.,
if the user interface needs to be split up amongst several
screens, controls appearing inside the
group would typically be rendered on the same screen.
Finally, the hierarchy defined by nested group elements is used to determine the
traversal order specified by attribute
navindex on form controls.
Setting the input focus on a group results in the focus being set to the
lowest form control in the tabbing order within that
t is an open issue whether the binding attribute
is allowed on element
It might make authoring easier but makes
implementations significantly harder.
Note that this note is here because at one point in our
design we said that controls inside a
could use relative XPath expressions with the context being
set by the containing group.
Containers typically have an orientation and a direction.
box-orient CSS property specifies
the orientation of the group. It has values of
inherit. A horizontal group lays out its
children in a horizontal line, and a vertical group
stacks its children vertically.
CSS property specifies the direction of the group. It has values of
A normal horizontal group lays out its children from left to right, and a normal
vertical group lays out its children from top to bottom.
Direction within nested groups is inherited by default. If direction is omitted on the outermost group, it is assumed to have a horizontal orientation and normal direction.
<group> <textbox ref="/person/name"> <caption>Please enter your name</caption> </textbox> <textbox ref="/person/ssid"> <caption>Enter your SSID</caption> </textbox> </group>
When items are placed in a group without specifying any additional information about their size, then the sizes the children intrinsically. In other words, the group makes each child only as big as it needs to be. Notice that in the above example, the two form controls are only as big as they need to be, and that this in turn determines the size of the group (since we assume for simplicity that this group is not nested).
Widths can be specified for items inside a horizontal group. When an object specifies its width in CSS, it is telling the group that it would like to be that width. Similarly, heights can be specified in CSS for items in a vertical group. A non-nested group placed inside an enclosing CSS block will obey all the usual sizing rules of the block. For example, setting the width of a non-nested group to 100% ensures that the group is the maximum width permitted by the enclosing CSS block.
box-align property specifies how controls are aligned along the orientation
of the group. Its possible values are
The default value is
By default a horizontal group ensures that all children are the same height. Once a height is computed for a horizontal group, all of the children are stretched vertically to the height of the group (minus the CSS border and padding on the group). Similarly, a vertical group ensures that all its children are the same width. The stretch policy overrides any specified width or height values.
<group style="box-orient: vertical"> <output ref="/person/name"/> <output ref="/person/age"/> <output ref="/person/country"/> </group>
In addition to
stretch, a horizontal group can also align its children using the
bottom. A vertical
group can align its children using the values
When these values are used, the items are no longer stretched. They are sized intrinsically
and then aligned on the group axis according to the specified property value on the containing
The layout algorithm can be controlled by specifying the
degree to which items may flex i.e.,
the degree to which an item allows itself to be
Items in groupes fall into two categories:
inflexible. Inflexible objects will not grow, even when there is
extra space left over in the group.
When several objects in a group are flexible, the extra space is divided
among the objects based on how flexible they are. The group determines how
much space to give an object by adding up the flex values on all of its
children. An object gets an amount of extra space equal to the percentage
of flex that it is responsible for.
For example, if two objects have a flex of 1, then after both objects are given their preferred sizes, the first object gets 1/(1+1) = 1/2 of the extra space, and the second object also gets 1/2 of the extra space.
<group style="box-orient: horizontal; width: 200px"> <textbox style="box-flex: 1" ref="/person/name> <caption>Please enter your full name: </caption> </textbox> <textbox style="box-flex: 1.5" ref="/person/age> <caption>How young?</caption> </textbox> </group>
For inflexible objects, the specification of the
height CSS properties can be used to
specify a preferred size. If these properties are omitted,
an inflexible object will be sized intrinsically, i.e., it will be given
the minimum amount of space required to lay out the item.
With flexible objects, there are more options. Just as with inflexible
height properties can be used to specify a preferred
size. Unlike inflexible objects, however, this size is only a guideline.
A flexible object will stretch as necessary. It will also
shrink if required until it can shrink no more (e.g.,
when the object hits its minimum required intrinsic size).
<group style="box-orient: vertical"> <textbox style="box-flex: 1; height:1000px" ref="/person/name"> <caption>Please enter your name:</caption> </textbox> </group>
In the above example if the group were to shrink, the
textbox being flexible would shrink--despite its
preferred height of
1000px. The group
continues to shrink minimum required height for the
textbox is reached. After that, the textbox can
shrink no further. If the group were to continue to
shrink, the form control's contents would be
clipped, and a portion of the control would no
longer be visible.
For a more fine-grained control of
minimum and maximum sizes, the
CSS properties can be used. When specified, these
properties provide extra information to the group as
it shrinks and grows the object in question.
In a horizontal group, for example, if a minimum width is specified, then the flexible object will not be allowed to shrink below that width. If a maximum width is specified, then the flexible object will not be allowed to grow beyond that width.
The above example demonstrates the use of
within a vertical group. In the first
image the group has been shrunk until it is smaller than 100 pixels in
height. Because the
iframe has a specified minimum height of 100 pixels,
it is not allowed to shrink any further, and so as the group falls below 100
iframe gets clipped, and portions of it become invisible.
In the second image, the group has been expanded past 300 pixels in
height. Even though the group is getting bigger, the extra space is not
being consumed by the
iframe, because its maximum height of 300 pixels has
been reached. It will grow no further.
Below is another example illustrating min and max width.
Example unavailable at publication time
In the above example, the group has been stretched so that it is very wide. The first child has a maximum width of 50 pixels, and it divides the excess space equally with the second child until its maximum width has been reached. After that, since it is not allowed to grow any further, the remaining space all goes to the second child.
When all of the items within a
element are inflexible or when all objects have
grown to their maximum sizes and can stretch no
further, extra space may be left over in the group.
An additional property can be used to dictate how
any additional space should be distributed between
objects. The CSS property
the possible values of
In the above example, the button is centered within the group using the
box-pack properties together. The former centers the button vertically, and
the latter centers the button horizontally.
Items within a group may use the CSS
overflow property to obtain horizontal and
vertical scrollbars as needed. Flexible objects that shrink below their minimum intrinsic
size (but that still have a size greater than a specified CSS minimum) can display
scrollbars using the
overflow property. If overflow is not specified,
the object will be clipped instead.
Whether an element is inline or block when placed directly inside a group is irrelevant. Objects
will be flowed horizontally or vertically based off the
When any raw text nodes are encountered directly inside a group, an anonymous block is constructed to wrap the text. This anonymous block then participates in the layout as a single item.
|Editorial note: Raman
|March 12, 2001
|Notice that we originally started by creating
an equivalent of
the present design of the XForms UI layer, and given
that conditional construct
case can take
there is little left in this construct that is
additional to what is in XHTML
therefore suggest simply reusing
bind XForms specific behaviors through CSS
e.g., a stack of cards for example? The way I am
thinking of this is that whether it is a stack of
cards shown one at a time, or a sequence of tab
dialogs is a presentation issue and might therefore be
best left to CSS as we have done with the rest of the
presentational issues in XForms.
Subpages provide a means to present XForms one bit at a time, breaking a complex
task into smaller, simpler parts. Presentation of a subpage can occupy the entire
"page" or just part of a page. Different presentations are possible, e.g. a
stack of pages with visible name tags, or as a set of buttons for flipping
through the stack or navigating directly to a particular subpage. One possible
representation is a
formset element enclosing one or more
elements, each of which starts with a
As the name implies
subpage is not specific to XForms--our intent
is to design
subpage so that it can be used within XForms--and
more generally within XHTML to create presentations where document views are
presented to progressively reveal the document
structure and content.
|Table of Contents