XForms is gaining momentum rapidly, with support available for common browsers using extensions or plugins, and through things like the IBM® Workplace Forms technology (see Resources). Its flexibility and power make it attractive to Web developers, and its small footprint and client-side processing make it attractive to systems administrators. The W3C is currently reviewing XForms 1.1 as a Working Draft document (1.0 is an official Internet Recommendation, which puts it on par with things like XHTML, PNG, and CSS), and IBM is currently spearheading an effort to merge competing XML-based forms standards with the features and abilities of XForms.
This article shows you how to create an XForms-based form using any of the available controls, how to create a data model, and the different types of basic submission actions that are available. Part 1 covered various browsers and their plugins that are necessary for viewing and interacting with XForms documents, so those items won't be covered again here. If you are following along, or you already have a plugin working with your favorite browser, you can jump in and download the code for this article and view the example XForms.
In the Part 1 of this series, you created a very basic form, something with a single text entry field and a single submit button, which would send a query off to an imaginary search engine located on the localhost (see Figure 1). This sort of form is still quite common, although it's usually not isolated on its own Web page.
Figure 1. A very basic Web form
This is a great starting point, so let's take a look at the XHTML and XForms code (Listing 1). The XForms-specific bits have been placed in bold text so that they're easier to pick out; the rest of the document is pure XHTML 1.1 Strict.
Listing 1. A starting point
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Search Form</title>
<xf:model>
<xf:submission action="http://localhost/imaginary-search-engine"
method="get" id="submit-search"/>
</xf:model>
</head>
<body>
<h1>Search Form</h1>
<p>
Enter a search string, then click the Search button.
</p>
<p>
<xf:input ref="query"><xf:label>Find:</xf:label></xf:input>
<xf:submit
submission="submit-search"><xf:label>Search</xf:label>
</xf:submit>
</p>
</body>
</html>
|
After adding the XForms namespace (with the xf: prefix), you've got an <xf:model> block declaring a submission action named submit-search, which will submit the specified search string using the standard HTTP GET method. Down in the <body>, <xf:input> and <xf:submit> elements make up your simple form, an input field and a submission button, which will trigger the action declared in the <xf:model>.
If you'd like to experiment with this, go right ahead; there's nothing special about the proximity, order, or location of the <xf:input> and <xf:submit> elements; they can be anywhere in the <body> of the document. The input widget presentation of the form is decoupled from its data model.
Because you're going to use this as a starting point for the rest of the article's XForms documents, there are also XML namespace declarations for XMLSchema and xml-events, two complementary standards that XForms leverages to provide standard data types and form events, respectively.
Part of the appeal of XForms is the way it separates the data model from the presentation. As you can see back in Listing 1, the model (inside of the <xf:model> block) lives on its own up in the <head> of the XHTML document.
Of course, that model is completely empty except for a single submission action. It doesn't contain any data!
But wait, it does. The system (in this case, the XForms-supporting browser) creates one for you (see Listing 2), containing the data fields referenced in the form.
Listing 2. The full <xf:model> implied by the simple form
<xf:model>
<xf:instance>
<data xmlns="">
<query/>
</data>
</xf:instance>
<xf:submission action="http://localhost/imaginary-search-engine"
method="get" id="submit-search"/>
</xf:model>
|
Explicitly including an instance like this adds an extra level of verification to your form; fields referenced by form controls (such as the text field and submit button in the simple sample form) must exist in the model instance. Controls that reference non-existent instance elements will either fail to render, or generate an error message (depending on your XForms implementation).
If you explicitly declare a data instance, you can use it to define default values simply by putting them inside the field elements. Listing 3 shows you the model from Listing 2 with a helpful default value for the query (see Figure 2).
Listing 3. Including default values directly in the
<xf:instance>
<xf:model>
<xf:instance>
<data xmlns="">
<query>One or more search keywords.</query>
</data>
</xf:instance>
<xf:submission action="http://localhost/imaginary-search-engine"
method="get" id="submit-search"/>
</xf:model>
|
Figure 2. Include data in your model instance for helpful hints or sensible defaults
Hidden values, hidden controls
XForms sends a complete XML document (the data model instance) when the user activates a submission action. You can include any data you want when you're creating a model instance.
This frees you from the need to include hidden controls in your forms. If you have data that needs to be sent to the form processor on the server, but that doesn't need to be presented to the user (or that needs to be constant), add it to the model instance (see Listing 4).
Listing 4. Include hidden or constant data in the instance, not the form
<xf:model>
<xf:instance>
<data xmlns="">
<query>One or more search keywords.</query>
<engine-version>2</engine-version>
<results>25</results>
</data>
</xf:instance>
<xf:submission action="http://localhost/imaginary-search-engine"
method="get" id="submit-search"/>
</xf:model>
|
In this example, the <engine-version> and <results> are never referenced by the form controls and are never seen by the user (unless they view the page source). They're sent to the imaginary-search-engine as part of the query, and the imaginary-search-engine can use them to select a search engine and set the number of results to return.
If you have a large data model, or you have data that needs to be hidden from users, you can load an instance from an external XML file (see Listing 5).
Listing 5. A simple model instance in an XML file
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
<query>One or more search keywords.</query>
<engine-version>2</engine-version>
<results>25</results>
</data>
|
Change the <xf:instance> to reference your instance URL (see Listing 6) and you're in business.
Listing 6. Referencing an external model instance
<xf:model>
<xf:instance src="search-instance.xml"/>
<xf:submission action="http://localhost/imaginary-search-engine"
method="get" id="submit-search"/>
</xf:model>
|
Because the <xf:instance>'s src attribute can load any XML data from any URL, you can use XForms to edit or present literally any data. Most XForms implementations limit the source document's URL to the same domain, although some let you configure a list of allowed sites that can also be trusted.
When you load an XML file as your data instance, you might not have control over the XML; the data might be provided by a database or some other application. How can you refer to specific elements in the XML? So far, you've only seen references to elements that match up with the data model.
The data model references used by the XForms form elements are actually XPath expressions, so you can use them to refer to any element in the model. Listing 7 shows you an expanded instance that includes some nested elements.
Listing 7. A more complex data model instance
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
<query>One or more search keywords.</query>
<engine-version>2</engine-version>
<results>25</results>
<some>
<additional>
<info status="important">Nested info.</info>
</additional>
</some>
</data>
|
You can access the <info> element using the XPath expression some/additional/info (or /data/some/additional/info if you want an absolute path) and the <info> element's status attribute with some/additional/info/@status. Listing 8 shows a form that you could use to edit this data file, assuming that your Web server supports the PUT method (you'd probably want to protect that capability behind some sort of authentication).
Listing 8. Editing more complex XML data
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Search Form</title>
<xf:model>
<xf:instance src="http://localhost/~chrish/data.xml"/>
<xf:submission action="http://localhost/~chrish/data.xml"
method="put" id="submit-edit"/>
</xf:model>
</head>
<body>
<h1>XPath</h1>
<p>
Change the info and status!
</p>
<p>
<xf:input ref="some/additional/info"><xf:label>New
info:</xf:label></xf:input><br/>
<xf:input ref="some/additional/info/@status"><xf:label>New
status:</xf:label></xf:input>
<xf:submit
submission="submit-edit"><xf:label>Save</xf:label></xf:submit>
</p>
</body>
</html>
|
XPath is an excellent complementary technology for XForms on both the client and the server; once you've mastered XPath, you can use it in your forms, and in the form processor.
So far, you've only seen the <xf:input> and <xf:submit> controls, but XForms provides a wide range of form controls. Let's take a quick look at them and their HTML equivalents.
<xf:group> (HTML <fieldset>) is used to logically group controls together in a section of the form. Listing 9 shows you how to use <xf:group> to label three input fields.
Listing 9. Grouping controls
<xf:group> <xf:label>Personal Information</xf:label> <p><xf:input ref="lastname"><xf:label>Last name:</xf:label></xf:input></p> <p><xf:input ref="firstname"><xf:label>First name:</xf:label></xf:input></p> <p><xf:input ref="address"><xf:label>Address:</xf:label></xf:input></p> </xf:group> |
<xf:input> (HTML <input type="text">) displays a standard text input field; you've already seen this one in action several times.
<xf:secret> (HTML <input type="password">) displays a text input field where the input is obscured, suitable for entering passwords or other secret data. <xf:secret> works exactly like <xf:input> in the document source.
<xf:select appearance="full"> (HTML <input type="checkbox">) provides the user with one or more selectable items and lets you select multiple items. Listing 10 shows you a sample.
Listing 10. Multiple selection control
<xf:select ref="potato-chips" appearance="full"> <xf:label>Favourite flavours:</xf:label> <xf:item><xf:label>Dill Pickle</xf:label><xf:value>dill</xf:value></xf:item> <xf:item><xf:label>Ketchup</xf:label><xf:value>ketchup< /xf:value></xf:item> <xf:item><xf:label>Plain</xf:label><xf:value>plain< /xf:value></xf:item> <xf:item><xf:label>Salt & Vinegar</xf:label><xf:value>snv</xf:value></xf:item> </xf:select> |
<xf:select appearance="minimal"> (HTML <select multiple>) is used to select one or more items from a menu or list; using minimal for the appearance attribute attempts to render the item list in a smaller area.
<xf:select1> (HTML <input type="radio">) is similar to <xf:select>, but only lets the user choose one item from the list. It can be rendered as a list of radio buttons, a scrollable selection area, or a menu, and you can use the appearance attribute to provide a hint for the renderer.
<xf:select1> with nested <xf:choices> (HTML <select> with nested <optgroup>) lets the user select one item from a list organized into groups. The label of the <xf:choices> sub-list is rendered in the list, but can't be selected. Listing 11 shows you a drinks' list that lets the user opt out, or select from a list of possible non-alcoholic or alcoholic beverages.
Listing 11. Selecting one item from several groups
<xf:select1 ref="drink">
<xf:label>Drink:</xf:label>
<xf:item><xf:label>None</xf:label><xf:value>none
</xf:value></xf:item>
<xf:choices>
<xf:label>Soft drinks</xf:label>
<xf:item><xf:label>Juice</xf:label><xf:value>juice
</xf:value></xf:item>
<xf:item><xf:label>Milk</xf:label><xf:value>milk
</xf:value></xf:item>
<xf:item><xf:label>Soda</xf:label><xf:value>soda
</xf:value></xf:item>
<xf:item><xf:label>Water</xf:label><xf:value>water<
/xf:value></xf:item>
</xf:choices>
<xf:choices>
<xf:label>Wine and beer</xf:label>
<xf:item><xf:label>Beer</xf:label><xf:value>beer<
/xf:value></xf:item>
<xf:item><xf:label>Red
wine</xf:label><xf:value>redwine</xf:value></xf:item>
<xf:item><xf:label>White
wine</xf:label><xf:value>whitewine</xf:value></xf:item>
</xf:choices>
</xf:select1>
|
<xf:textarea> (HTML <textarea>) gives the user a multi-line text input field; use CSS styling to control the size of this area if the default isn't suitable.
<xf:trigger> (HTML <input type="button">) renders an action button. Buttons have no predefined behavior, so you must attach an action to them, which will be triggered when the button is activated. Listing 12 shows an <xf:trigger> that activates a JavaScript™ function named calculate().
Listing 12. A button that calls the JavaScript function
calculate()
<xf:trigger>
<xf:label>Calculate</xf:label>
<script ev:event="DOMActivate" type="text/javascript">
calculate();
</script>
</xf:trigger>
|
Note that this is the first time the ev: namespace has been used that was declared way up in the basic form example. It lets you reference the standard XML Events attribute, ev:event, which tells the trigger when to activate its script.
<xf:trigger> (HTML <input type="image">) can also be used to add image buttons to your form; just insert an <img> element inside the <xf:label> element, or use CSS to apply an image to the element's background.
<xf:trigger> (HTML <input type="reset">) can be used to add a Reset button if you're upgrading some old forms from HTML to XForms (maybe the specification for the upgrade requires "all existing functionality," including useless Reset buttons). Listing 13 shows you how to create a form reset button, but don't use this in new forms: no end user ever hits the Reset button on purpose.
Listing 13. Implementing a useless historical artifact, the Reset button
<xf:trigger>
<xf:label>Reset</xf:label>
<xf:reset ev:event="DOMActivate"/>
</xf:trigger>
|
<xf:upload> (HTML <intput type="file">) is used to allow file uploads. It's slightly more involved than the other controls, because it needs to use a special <xf:submission> method, form-data-post (see Listing 14).
Listing 14. The
<xf:submission> method used to upload files
<xf:model>
...
<xf:submission action="http://localhost/upload-engine"
method="form-data-post" id="upload"/>
</xf:model>
|
Down in the form, the <xf:upload> element looks just like <xf:submit> or <xf:input> (see Listing 15).
Listing 15. Use
<xf:upload> to upload a file<xf:upload ref="upload"><xf:label>Upload a file:</xf:label></xf:upload> |
There are also controls that don't exist in HTML.
<xf:output> lets you include values as text in the document. For example, in Listing 7 you added a <results> element to the data model. Even though this isn't something the user can modify, you could change it by editing the model (especially if you're using a model defined in an external XML file). You can use the <xf:output> element to present this information to the user (see Listing 16).
Listing 16. Using
<xf:output> to display data from the model<p> Your search will return a maximum of <xf:output ref="results"> matches. </p> |
<xf:range> lets you present the user with a range slide or something else appropriate for getting a constrained value. For example, you could use three of these to have the user input red/green/blue values for a color to use when highlighting search results (see Listing 17).
Listing 17. Using range input controls
<p> Keyword highlight:<br/> <xf:range ref="r" start="0" end="100" step="1"><xf:label>Red</xf:label></xf:range><br/> <xf:range ref="g" start="0" end="100" step="1"><xf:label>Green</xf:label></xf:range><br/> <xf:range ref="b" start="0" end="100" step="1"><xf:label>Blue</xf:label></xf:range> </p> |
Now that you've seen the XForms input controls (and one output control), you can look at the different submission actions.
The XForms standard supports the usual HTML form submission methods, but, where HTML requires a method and enctype to specify the submission method, XForms requires only a method.
<xf:submission method="form-data-post" action="url"/> is the same as <form method="post" enctype="multipart/form-data"> in HTML, and can be handled at the receiving URL in the same way.
<xf:submission method="get" action="url"/> is the same as <form method="get"> in HTML.
<xf:submission method="urlencoded-post" action="url"> is the same as <form method="post" enctype="application/x-www-form-urlencoded"> in HTML.
In addition to these HTML-compatible submission methods, XForms defines two new submission actions, method="post" and method="put".
The method="post" action posts the form's data model instance to the receiving URL as an XML document, suitable for processing with XSLT or any other XML manipulation technique. No additional encoding or escaping is required on the client, and no additional processing (beyond the standard XML parsing) is required on the server.
The method="put" action puts the form's data model instance to the destination URL as an XML document. If the server supports the PUT method, and you've got permission to use it on the destination URL, the XML document will replace the file at the destination URL. This can be used to edit "any" XML document in-place by loading the data model instance through the same URL that you'll later use with the put action.
The pure XML post and put methods are part of the appeal of XForms, and bring a level of flexibility to your data processing.
XForms provides a consistent and clear XML-based data model that lets you include arbitrary XML directly in the document, or in external files loaded during page processing. The standard supports equivalents for all of the standard existing HTML form controls, in addition to a couple of other helpful controls for range selection and displaying data. The basic XForms submission actions cover the legacy HTML submission methods, as well as two more XML-based methods. This article provided a quick tour through all of these, giving you a good starting point for your own XForms experiments.
| Description | Name | Size | Download method |
|---|---|---|---|
| Part 2 sample code | xforms2.zip | 3KB | HTTP |
Information about download methods
Learn
-
Visit the XForms home at W3C.
-
XForms.org: The Nexus for Intelligent Web Apps contains a treasure-trove of information and links on XForms.
-
Read about Web Forms 2.0, a similar but competing spec.
-
Get ready for XForms (devleoperWorks, Septebmer 2002) provides a useful overview of this important technology.
-
For an excellent introductory tutorial on XPath, see Get Started With XPath (developerWorks, May 2004).
-
For an article demonstrating the relative strengths of using XPath, read The Java XPath API (developerWorks, July 2006).
-
For an article that looks at some of the spcific features of XPath, read XML for Data: What's New in XPath 2.0? (developerWorks, September 2002).
-
Read Part 1 in this series, Introduction to XForms.
-
Read Part 3 in this series, Introduction to XForms.
-
For an overview of how XML Events came about, what it's useful for, and how it works, see Introduction to XML Events (developerWorks, November 2004).
-
Read John Boyer's blog on XForms, Web Forms 2.0 and the future of XML content on the web.
-
SVG and XForms, a Primer (developerWorks, November 2003) provides an overview of the two technologies and highlights the potential synergies between them.
-
Read XForms Essentials by Micah Dubinko from O'Reilly Media.
-
For a good starting point for XForms research, read
Ten Favorite XForms Engines from XML.com.
-
For an interactive, cross-platform tutorial on W3C XForms, visit the XForms institute.
-
Get a historical perspective on the origins and purpose of XForms in this brief history of SGML.
-
To get a good grounding in XML, read the Introduction to XML tutorial (developerWorks, August 2002).
-
Learn all about XML at the developerWorks XML zone.
Get products and technologies
-
Get the XForms extension for Mozilla, Firefox, or Seamonkey.
-
Get the XForms plugin for Internet Explorer 6.
-
Get the Trial: Lotus Forms (formerly Workplace Forms product).
-
Get the XML Path Language (XPath)
Version 1.0 specification from the W3C.
-
Get the XML Events specification from the W3C.
Discuss

Chris Herborth is an award-winning senior technical writer with more than 10 years of experience writing about operating systems and programming. When he's not playing with his son Alex or hanging out with his wife Lynette, Chris spends his spare time designing, writing, and researching (that is, playing) video games.
Comments (Undergoing maintenance)





