W3C XForms (the word is both a singular and plural form) is an update to HTML forms and provides an extensible means to include richer, more dynamic forms in HTML documents. You can also use XForms to create Web forms more quickly and easily. XForms enables support for multiple devices and structured form data, like XML documents. With XForms, developers can also generate dynamic Web forms without scripting, to include multiple forms within the same page, and to constrain data in various useful ways. Finally, while each of the XForms parts -- namely the data model, the view, and the controller -- is completely separable and usable with other technologies, significant additional value can be realized through how well these parts integrate together into an application.
In this primer, we present an introduction to some of the most useful aspects of XForms, and guide you through a simple application example. This article is based on the XForms 1.0 Working Draft, issued in July 2002 (see Resources for this and other useful links).
An historic overview
Some of the concepts embodied in XForms can be traced back to Standardized General Markup Language (SGML). One of the intentions of SGML was to distinguish textual content from its presentation by embedding the textual content in machine-readable tags. This meant, among other things, that content and presentation could be developed by different people. It also introduced the flexibility of reuse.
Hypertext Markup Language (HTML), an SGML document type, also encloses content within meaningful tags. However, HTML does not continue the notion of separating content from presentation. The relative simplicity of creating Web pages with HTML led to its near universal adoption at the same time that the Internet infrastructure became widely available. The standardization of HTML tags resulted in a language that could be understood across Web browsers. However, as business goals drove Web developers to attempt to produce more sophisticated and dynamic sites, the language's limitations became apparent.
Listing 1. An example HTML form
... <!--Ellipsis represent parts that are missing--> <FORM action="http://www.example/ " method="post"> <P> <INPUT type="radio" name="HairColor" value="Brown">Brown<BR> </P> </FORM>
In Listing 1, notice how
value="Brown" are specified within the same code that creates the user interface. This HTML snippet also hard-codes the type of widget -- a radio button, in this case -- that will be displayed in the user interface. Thus, this form would not be rendered correctly on platforms that do not support radio buttons. Because HTML forms can include embedded data and hard-coded decisions, changing the presentation of an individual form is not easy. Standardization of HTML has also meant that the HTML tag set was not designed to be extensible by an individual developer, limiting the possibility to customize the language or improve its expressive power.
The introduction of Extensible Markup Language (XML) and Extensible Stylesheet Language (XSL, an XML document type) attempted to address these problems. Unlike HTML, the combination of XML documents with XSL transformations enables the separation of data from presentation. Fields like
value can be stored as XML data, while the presentation can be created by transforming the XML document into HTML through an XSL transformation. This allows developers to steer clear of many of the hard-coding decisions that are unavoidable when using HTML forms. The same XML data can be presented in a variety of styles, usually through the use of different XSL style sheets; conversely, a single XSL transform can render non-uniform XML in a uniform style. In addition, XML/XSL affords developers extensibility that HTML does not.
Although HTML generated by applying XSL transforms to XML content provides many advantages over static HTML, the added functionality comes at a price. First, a server that handles the transformation of XML into HTML won't perform as well as a server that is serving static HTML alone. The transformations themselves require server cycles; in addition, the form might require multiple client-server round trips. Second, implementing XML with XSL transformation requires developer skills that aren't as widely available as those required to implement HTML alone.
XForms: Next-generation Web forms
As noted, the XForms specification was motivated by the need for an extensible means to include richer, more dynamic forms in HTML documents, while at the same time making Web forms easier and faster to create. XForms can be thought of as an extension module for XHTML (an XML-compliant form of HTML). The XForms spec introduces a predefined set of tags, elements, and attributes that ease the creation of Web forms. Browsers with XForms processors can render XForms documents on the client. This enables the developer to avoid performance costs associated with server round-trips to update the Web form. (You can also use a server-side XForms interpreter to translate XForms documents into HTML if you wish.) Most importantly, XForms splits a form's data model, view, and controller. These parts are further decomposed into even finer reusable levels. For instance, XForms differentiates a form's view into its presentation and purpose.
The data model part of XForms enables you to declare data items and structure separate from any set of widgets used to display the data values. XForms defines the means for binding these data items to the display widgets separately from the declaration of the data mode itself. In addition, declarative means of acting on changes in value for any particular data item are also defined.
XForms widgets are abstract in nature, so different platforms can choose to implement them in different ways. For example, while a
<radioButton> tag in HTML may have only one presentation across platforms (such as a drop-down menu), the
<select1> widget (see Appendix C4) in XForms may result in a drop-down menu on a PC browser or a list of radio buttons on a PDA. The purpose of the
<select1> control, however, remains the same -- it affords a user the ability to select a single element from a set of items.
Hello World: An XForms introduction
In this article, we address the important aspects of a handful of basic XForms tags. We cover the tags' usage and syntax as well as the meaning of some of their common attributes. When we discuss specific tags, we provide links to this article's appendices, where you can view the full specification.
First, we present the familiar "Hello World" example so you get a first look at form structure and an introduction to the XForms syntax. It also provides a means to compare XForms to other markup languages. In subsequent sections, we present parts of the e-commerce order form that serves as the primary example for the tutorial.
Listing 2 shows the complete "Hello World" example, while Figure 1 shows how the example might look rendered in an XForms-compatible browser. It is important to take note of the document's basic structure, as every XForms document will have a similar layout. You'll see that the model is defined within the head (see The XForms model) and that the view is defined within the body of the document (see XForms user interface). Note also that namespaces are specified within each HTML tag. To avoid naming conflicts, you should use the namespace prefixes whenever possible.
Listing 2. Hello World
<!--Hello World Example--> <html xmlns= "http://www.w3.org/1999/xhtml" xmlns:xforms="http://www.w3.org/2002/01/xforms" xmlns:my="http://www.example.com/my-data"> <head> <!--The Model is defined within the head of the xhtml document--> <xforms:model> <!--The instance is defined within the model--> <xforms:instance> <my:data>Hello World</my:data> </xforms:instance> </xforms:model> </head> <body> <!--The view is defined within the body of the document--> <xforms:group> <xforms:output ref="/my:data"> <xforms:label>Output Control Example</xforms:label> </xforms:output> </xforms:group> </body> </html>
Figure 1. Rendering of 'Hello World'
Please note that, as there are currently no production-quality processors for the XForms language, all example renderings are artistic illustrations and do not come from a particular XForms implementation. (For links to beta-release XForms processors, see Resources.)
The remainder of this article focuses on an example e-commerce order form. This order form includes sections to enter customer information, calculate price information, and list the items in the shopping cart. The first part of the tutorial walks through the definition of the model, while the second part shows the view definition. The example code is included in its entirety in Appendix A. Figure 2 shows a rendering of the completed order form example.
Figure 2. The rendered order form
The XForms model
The XForms model represents the form's content, and therefore does not change from presentation to presentation. The model is composed of the form's data and logic components. The form's data is contained within the instance (more on that shortly); it includes all of the form fields as well as any necessary temporary storage. The form's logic components define its behavior. These logic components are defined with event handlers, data bindings, and submission information, all discussed in later sections.
XForms allows for multiple models to be defined within the same form. This is useful when you want one application to support multiple functions. For example, a personal portal may be composed of a stock ticker model, a calendar model, and so on. If you have multiple models defined, you can use the
id attribute to uniquely identify each of them. Listing 3 is the skeleton code for the order form example:
Listing 3. Skeleton code for order form example
<HTML xmlns="http://www.w3.org/1999/xhtml" xmlns:xforms=http://www.w3.org/2002/01/xforms xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"> <head> <title>XForms: Order Form</title> <xforms:model> ... <!--Instance and Logical Components--> </xforms:model> </head> <body> ... <!--User Interface goes here--> </body> </HTML>
You can see here that the model is defined within the head of the document, as stated earlier. The next step is to declare instance data.
For specification information on the XForms model, see Appendix B6.
The instance data is defined within the model. It represents all of the information that is passed to the back end and any temporary storage that is needed within the model. Each instance, however, can only contain a single XML data tree -- in other words, there can only be one root node.
The instance is either defined locally within the model or points to existing XML data on a remote machine through a URI. Listing 4 defines an instance locally in the order form, called
Listing 4. Defining a local instance
<xforms:model> <xforms:instance> <OrderInfo> <PersonalInfo> <Name> <First></First> <Middle></Middle> <Last></Last> </Name> <Address> <Street></Street> <City></City> <State></State> <Zip></Zip> </Address> </PersonalInfo> <PriceInfo> <SubTotal></SubTotal> <TaxTotal></TaxTotal> <TaxRate></TaxRate> <Total></Total> </PriceInfo> <TaxInfo> <CT>.060</CT> <NY>.085</NY> <NJ>.083</NJ> </TaxInfo> <ShoppingCart> <ProductInfo name="itm1"> <Quantity>5</Quantity> <Description>Wht. Chocolate Bars</Description> <UnitPrice>1.45</UnitPrice> <ItemTotal></ItemTotal> </ProductInfo> <ProductInfo name="itm2"> <Quantity>8</Quantity> <Description>Blk. Chocolate Bars</Description> <UnitPrice>1.45</UnitPrice> <ItemTotal></ItemTotal> </ProductInfo> <ProductInfo name="itm3"> <Quantity>2</Quantity> <Description>Car. Filled Choc</Description> <UnitPrice>1.80</UnitPrice> <ItemTotal></ItemTotal> </ProductInfo> </ShoppingCart> </OrderInfo> </xforms:instance> ... </xforms:model>
In Listing 4,
OrderInfo has four main components:
PersonalInfocontains all of the information that you want to obtain from the user
PriceInfoincludes the information required to calculate the bill
TaxInfocontains static information about state tax rates (for simplicity, this example only defines the tax rates of New York, Connecticut, and New Jersey)
ShoppingCartis the list of items the user intends to buy
Traditionally, one often thinks of form data as simply the information the form acquires from the user. The
TaxInfo sections, however, highlight how you can use instance data as temporary variables and constant information, respectively.
As an alternative, Listing 5 shows how you would instantiate an instance by referencing a remote XML resource.
Listing 5. Referencing a remote instance
<xforms:model> <xforms:instance href="http://www.example.com/OrderFormData.xml"/> ... </xforms:model>
For specification information on instance data, see Appendix B5.
Bindings, dependencies, and constraints
You can bind values to instance data in XForms using two ways: Data can be made dependent on other data, or it can be bound to input provided by the user. This section covers the former method; the latter -- user input binding -- is discussed in XForms user interface.
<bind> tag is defined within the model; it allows you to make instance data dependent on other data. For example, the statement in Listing 6 binds
TaxTotal to the computed tax (
TaxRate multiplied by
Listing 6. bind statement
<!--Within the Model--> <xforms:bind ref="/OrderInfo/PriceInfo/TaxTotal" calculate="/OrderInfo/PriceInfo/TaxRate * /OrderInfo/PriceInfo/SubTotal"/>
ref attribute refers to the node that you wish to bind --
calculate attribute defines the value that you want to bind to the node; in this case, you bind
TaxTotal to the product of
calculate supports other simple functions in addition to multiplication (refer to Appendix D for the full list).
You can use the
relevant attribute to define the conditions under which a
bind tag is valid or should be applied. For example, you can bind the
TaxRate as shown in Listing 7:
Listing 7. bind statement with relevant attribute
<!--Within the Model--> <xforms:bind ref="/OrderInfo/PriceInfo/TaxRate" calculate="/OrderInfo/TaxInfo/CT" relevant="/OrderInfo/PersonalInfo/Address/State = 'CT'"/>
<bind> statement assigns
ref) to the Connecticut tax rate (
calculate) only if the user lives in Connecticut (
relevant condition). You need to define similar statements for New York and New Jersey, ensuring that
TaxRate is bound to the value for the appropriate state in any given case.
You can also use the
<bind> tag to constrain instance data in various ways -- by setting a data type with the
type attribute, for example. Listing 8 shows how to constrain the
SubTotal field so that it is always a decimal value:
Listing 8. bind statement with type constant
<!--Within the Model--> <xforms:bind ref="/OrderInfo/PriceInfo/SubTotal" type="xsd:decimal"/>
There are many other ways of constraining the instance data; see Appendix E for the full list. On a field-by-field basis, the XForms processor checks the instance data against its constraints. If the user enters data that violates any of the data constraints, the XForms-enabled browser can immediately provide feedback to the user. This assures that the back-end processes receive only well-formed data and also provides a greatly improved level of usability.
For specification information on bindings, dependencies, and constraints, see Appendix B2.
The order form model would be incomplete without defining some way of communicating with the back-end server. With the
action attribute, you can use the
<submission> tag to specify the call to invoke when the user is ready to submit, as shown in Listing 9:
Listing 9. submission statement
<!--Within the model--> <xforms:submission id="submit1" action="http://www.example/" method="post"/>
You can also specify the HTTP method, in other words,
post. We recommend that you always use
post in order to encapsulate XML content.
There can be multiple
<submission> blocks within the same model. Thus, you need to be sure to give each
<submission> tag a unique identifier with the
id attribute (for example,
id="sub"), since in the user interface these tags will be bound to submit buttons (see submit).
For specification information on
<submission>, see Appendix B9.
XForms user interface
The user interface defines how the data models instance is incorporated into the presentation of the page. It is expressed through both atomic (such as
<output>) and compound (such as
<switch>) controls. Atomic components are the actual widgets that developers can use to populate a form, while compound UI components are used to organize and group atomic objects. As mentioned earlier, both atomic and compound controls are not bound to a particular presentation as their HTML counterparts are, but are instead associated with a particular abstract purpose.
<switch> tags provide ways of combining atomic form controls into complex user interfaces. For example, in a large e-commerce form, you can group the atomic objects into sections -- for example, an address section, a payment section, and an item section. You can then take these groups and treat them as compound components. These compound objects can also be nested to create other compound controls.
The group is the simplest compound control: It is a basic container that groups controls together. Listing 10 shows how to group the various form controls so that you can later use that group as an object in a larger e-commerce form.
Listing 10. View skeleton of an address form example
<body> <xforms:group> <!--AddressForm form controls goes here--> </xforms:group> </body>
For specification information on groups, see Appendix B3.
<repeat> tag helps reduce the amount of redundant code in a form by allowing developers to apply the user interface template to a collection of instance data with the same type and structure. Within the order form example, we use a
<repeat> tag to display the items in the shopping cart, as shown in Figure 3:
Figure 3. The repeat section
Instead of explicitly writing a UI control for each item, we use a
<repeat> tag to iterate over the
ShoppingCart section in the instance in Listing 4.
Listing 11. repeat statement example
<xforms:repeat id="shoppingcart" nodeset="OrderInfo/ShoppingCart/ProductInfo"> <xforms:output ref="Quantity"/> <xforms:output ref="Description"/> <xforms:output ref="UnitPrice"/> <xforms:output ref="ItemTotal"/> </xforms:repeat>
nodeset attribute of the
repeat element in Listing 11 defines an XPath that is evaluated against the model instance. The
repeat element then iterates across this
nodeset for each of its nested controls.
In Listing 11, the
ref attribute refers to the values of fields in the
ProductInfo subtree. You can also refer to attribute values by preceding the XPath with an
@. For example, you could reference the
name attribute in each
ProductInfo with the following call:
ref = "@name"
Developers can use the
<repeat> tag to make their XForms documents shorter and more responsive to the actual data instance. Furthermore, the tag also enhances the expressive power of the XForms language: You do not need to know exactly how many items are in the shopping cart; the
<repeat> tag automatically traverses the instance tree and produces an output for every possible match.
For specification information on
<repeat>, see Appendix B8.
<switch> statement allows for dynamic UI generation. Within each
<switch> statement, there are
<case> statements that define conditions under which a different UI should be used. For instance, within the e-commerce form, after obtaining the personal information, vendors would like to know the payment method. A
<switch> tag can be used to branch on the payment type the user selects. If the user selects payment by credit card, a dynamically generated set of UI controls is displayed. Alternatively, if the user selects cash or any other payment method, the form generates another set of visual components. The
<switch> tag allows the UI to be user driven.
For specification information on
<switch>, see Appendix B11.
Atomic form controls
Atomic controls are the primitive components that developers can use to design a user interface. You can populate the three high-level controls just described with these controls. Let's take a look at a few atomic controls.
The most basic form control is the
<input> tag. As mentioned in Bindings, dependencies, and constraints, this is one of the ways to bind user-supplied data to the instance. An example of the
<input> tag from our address form is shown in Listing 12:
Listing 12. input statement
<!--In the User Interface--> <xforms:input class="ZipCode" id="zipcode" ref="OrderInfo/PersonalInfo/Address/ZipCode"> </xforms:input>
ref attribute specifies the XPath that the input data should be bound to. Since the
ref attribute is using XPaths to locate the instance location, if there are multiple node matches (for example, multiple
/AddressInfo/Address/Zip nodes), then
ref chooses the first match unless the developer explicitly designates the index to choose. In our example, the value that the user inputs for this input field is bound to
/OrderInfo/PersonalInfo/Address/ZipCode. A title for the input field has to be added by creating a
<label> child of the
<input> tag. (Note that the
<label> tag is one of a handful of optional tags that can be created within every form control. For a full list of such tags, refer to Appendix F.)
For specification information on
<input>, see Appendix B4.
<output> simply displays the values of instance data. In the example in Listing 13, you can use an
<output> control to print the calculated tax:
Listing 13. output statement
<!--In the User Interface--> <xforms:label class="label">Tax Amount $</xforms:label> <xforms:output class="Amount" id="taxtotal" ref="OrderInfo/PriceInfo/TaxTotal" />
This tag is similar to
<input> in many ways; the only difference is that
<output> is read only.
For specification information on
<output>, see Appendix B7.
<action> tag is an XML event handler. It is populated with a set of declarative XML handlers that control most standard use cases, thereby eliminating the need for complex scripts. Those scripts are often lengthy and complicated, and are not necessarily supported across platforms. With the packaging of XML events into a set of easily invoked tags, dynamic content is both easy to include and guaranteed to work on all XForms-enabled platforms.
event attribute specifies which event the
<action> tag should listen for. For example, Listing 14 shows how a
refreshForm action is defined in our order form.
Listing 14. action statement
<!--In the User Interface or embedded in a UI form control--> <xforms:action event="click" > <xforms:refresh ev:event="xforms:activate"/> </xforms:action>
click event occurs, the action event handler catches the event and invokes the
It is possible to have multiple actions within the same
<action> tag. When the event handler is activated, it invokes all the actions defined within its body. (For a full list of XForms declarative actions, refer to Appendix G.) When placed within an
<action> tag, these common actions allow client-side browsers to generate content in response to user-driven events.
<action> tags can also be defined within the model. In the next section, you'll see how to embed an
<action> tag within a form control.
For specification information on
<action>, see Appendix B1.
Triggers are UI controls that perform an action when activated. For example, they could be buttons that respond to a user's mouse click. When activated, triggers fire off an XML event that is caught by the event handler defined with
<action> tags. You can define a trigger in XForms by making a statement like that in Listing 15:
Listing 15. Uneventful trigger statement
<!--In the User Interface--> <xforms:trigger> <label>My Refresh Trigger</label> </xforms:trigger>
Listing 16. trigger statement that does something
<!--In the User Interface--> <xforms:trigger> <xforms:label>Reset</xforms:label> <xforms:action event="click" > <xforms:refresh ev:event="xforms:activate"/> </xforms:action> </xforms:trigger>
When clicked, this trigger throws a
click event, which is caught by the
<action> tag event handler. This invokes the
For specification information on
<trigger>, see Appendix B12.
<submit> tag creates a trigger that, when clicked by the user, invokes the action defined within the
<submission> tag. (This is really an alias for a trigger that contains a dispatch event that is associated with a particular
Listing 17. submit statement
<!--In the User Interface--> <xforms:submit submission="sub"> <xforms:label>Submit</xforms:label> </xforms:submit>
For specification information on
<submit>, see Appendix B10.
With XForms, you can define Web forms in a way that successfully separates purpose from presentation. You focus more effort on the content of the form and the data being collected, and less on the style of presentation. The language defines a powerful event model that obviates the need for custom scripts to handle simple, form-related tasks.
With XForms, the developer's primary focus is on the data to be collected. Using standard XML schemas, the structure and type of the data is explicitly defined. XForms extends this model by allowing for the specification of additional constraints and dependencies. The XForms processor evaluates and enforces these constraints without the need for additional code. The processor checks data types and constraints before the data is submitted for processing.
The XForms specification also allows for the creation of dynamic forms through data-driven conditionality. You no longer must write special code to generate custom forms based on user responses. XForms can adapt forms on the fly, as data is collected and conditions change.
Navigation through XForms is handled by the XForms event model, independent of the client rendering. You can present the same XForms as a single page on one client and as multiple pages on another, without having to worry about saving state and presenting appropriate navigation controls.
Because of its concise specification and powerful features, forms created with XForms tend to be much easier to maintain than traditional Web forms. Code is not intermixed with presentation markup. Additional data type checking code is not necessary. Data structure is divorced from form presentation markup.
Regardless of whether XForms really is the ultimate solution for separating purpose and presentation, XForms is indeed the next generation of Web forms.
We want to express our gratitude to the people who helped on this paper. We'd like to thank Lauretta Jones and Sharon Greene for the hours of editing help and spirited support. Angel Diaz, Paul Matchen, Matt Callery, Samuel Dooley, T.V. Raman, and Rich Thompson also helped with their feedback and technical guidance.
- Participate in the discussion forum.
- Read about XForms on the W3C's site.
- Check out this list of Beta-released XForms processors.
- Read the W3C-hosted working draft of the XForms specification.
- Learn more about what's new in XHTML 2.0, including XForms, in "The Web's future: XHTML 2.0" (developerWorks, September 2002).
- Get a historical perspective on the origins and purpose of XForms in this brief history of SGML.
- Learn about XML events to help you understand how XForms work.
- Find more XML resources on the developerWorks XML technology zone, and more HTML resources on the Web development topic.
- Get Rational Application Developer for WebSphere Software, an easy-to-use, integrated development environment for building, testing, and deploying J2EE applications, including generating XML documents from DTDs and schemas.
- Find out how you can become an IBM Certified Developer in XML and related technologies.