4.2 Dynamic User Interaction with switch
A key feature of electronic forms is their ability to react to user input and use such dynamic updates to aid in rapid task completion. Thus, whereas paper forms are static, electronic forms typically aid the user in navigating through the various stages of a complex interaction by appropriately revealing or hiding sections of the form. This form of dynamic interaction is also commonly used to create task-oriented wizards that guide users through a given interaction. We described construct group in Section 4.1 for logically grouping user interface controls. Here, we describe construct switch , which can be used to hide or reveal selectively such logical groups of controls.
4.2.1 Anatomy of Construct switch
User interface construct switch holds sets of logically grouped controls and enables any one of these logical groups to be displayed to the user selectively. Element switch takes all common user interface attributes described in Section 3.2, and these can be used to advantage in styling the user interface.
In addition, XForms binding attributes can be used on element switch to establish an XPath context and thus aid in authoring relative XPath locators within binding expressions that appear within the body of construct switch . Each logical group of controls is encapsulated within child element case . Boolean attribute selected of element case determines the case that is currently active , that is, the group of controls currently displayed to the user. Setting this attribute to true results in the controls within that case becoming active. If none of the case children of a switch has selected set to true , the first case in document order is made active.
Each case is given a unique identifier via attribute id that is used later in activating a given case . Element case can hold all of the XForms user interface controls, as well as the various aggregation constructs described in this chapter, including construct switch itself.
Construct switch derives its power from the use of XML Events. XForms defines a declarative event handler, toggle , that is specifically designed for use with switch . As an event handler designed for use with XML Events, element toggle uses the attributes defined by module XML Events in binding to the desired event. Attribute case on handler toggle identifies a particular case in a switch to activate. Invoking handler toggle results in the specified case becoming selected; as a side effect, the case that was previously selected becomes inactive. Thus, the effect of invoking handler toggle with a specific value for attribute case is
4.2.2 A Simple Example of switch
We illustrate the use of construct switch with a simple example in Figure 4.3. The switch construct shown here contains two case elements. The first of these is initially active and contains an input control that collects the user's first and last names ; we show the visual rendering produced by X-Smiles in Figure 4.4.
Figure 4.3 switch can selectively reveal or hide portions of an interface.
< switch xmlns ="http://www.w3.org/2002/xforms" xmlns:ev ="http://www.w3.org/2001/xml-events" ref ="/person/ name "> < case id ="edit">< label >Editor</ label > < input ref ="first"> < label >First name</ label ></ input > < input ref ="last">< label >Last name</ label > < toggle ev:event ="DOMActivate" case ="view"/> </ input ></ case > < case id ="view"> < label > < output ref ="first"/>< output ref ="last"/> </ label > < trigger >< label >Edit</ label > < toggle case ="edit" ev:event ="DOMActivate"/> </ trigger ></ case > </ switch >
Figure 4.4. Initial state of the edit/view interface.
Notice that we have used XForms binding attributes on element switch to set up the XPath context for the rest of this example. As a consequence, all the user interface controls appearing within this switch can use relative XPath expressions when binding to the underlying data model.
The input control that collects the user's last name contains an event binding that attaches handler toggle to event DOMActivate . This handler is invoked when the input control receives a DOMActivate event, that is, the user completes entry in the input field. Attribute case of this toggle handler is set to refer to the second case element in the containing switch ; thus, finishing entry into the input control results in the second case becoming active. The user interface now switches to displaying the rendering shown in Figure 4.5.
Figure 4.5. switch can alternate between different portions of an interface.
This second case element contains a label that displays a greeting using the values just entered. This case contains a trigger that functions as a conceptual edit button by invoking a toggle handler that activates the first case element.
Notice that as a consequence, the switch shown in Figure 4.3 functions as a read-only display of the user's name that when activated turns itself into an input control that allows the user to update the value.
4.2.3 Model and Interaction-Based Switching
Construct switch is used to enable dynamic navigation through complex interfaces. It's also useful when delivering a user interface to devices with small displays where it is advantageous to reveal progressively a user interface. Notice that activation and deactivation of case elements within construct switch is driven through the user interface, that is, cases are made active or inactive based on user interaction events.
Contrast this with the rest of the XForms user interface, where all updates to the presentation happen as a result of changes to the underlying model. This interaction-based switching introduced by construct switch is by design and is not an oversight on the part of the XForms working group. We feel that interaction-based switching is a sufficiently useful feature to be treated as a first-class citizen, given our interest in being able to deliver complex user interfaces to small devices.
XForms supports an alternative form of dynamism that is completely model driven; this is achieved via model property relevant detailed in Section 5.3. Model property relevant is a boolean value that is computed dynamically at run-time and can affect the availability of portions of the interface that bind to relevant portions of the model. Model-based switching is a powerful XForms feature and can often lead to more flexible interfaces than the pure interaction-based switching afforded by construct switch . As an example, notice that switch can activate one and only one of the contained logical groupings encapsulated within the various case children. In contrast, model-based switching can hide or reveal more than one section of a user interface.
4.2.4 Creating Multipage Tab Dialogs Using switch
Construct switch can be used to advantage in authoring multipage wizards that allow the user to complete a complex task. When such a task consists of several conceptual pages , construct switch enables the delivery of a rich end-user experience by avoiding client-server round-trips when switching between the various pages making up the task.
Notice that the Web metaphor of serving a Web page for each dialog turn in a complex task works well for large displays where the user interface can encompass multiple entry fields in a given page. As a consequence, matching each dialog turn with a client-server round-trip can still deliver a satisfactory end-user experience.
But when deploying to small devices, the quantity of information that can be displayed at a given time, and consequently the amount of data that can be collected on any given page , is relatively small. In the case of a purely nonvisual interface, this may be as small as a single item of information. Introducing client-server round-trips for each turn in such a man-machine conversation can lead to rapid degradation of the end-user experience.
Construct switch can be used to alleviate this problem. A complex task consisting of multiple conceptual pages can be organized within construct switch with each case containing a portion of the user interface that has been tailored to the small display. Control trigger within each case element can be used to create navigation controls that allow the user to move through the various stages of the task. Notice that in this case, there is no client-server round-trip as the user transitions between various stages of the task. Using construct switch in these situations improves the end-user experience. It also eliminates the need to write on the server a device-specific controller component that manages the user's navigation through the various pages making up the task.
Consider the multipage insurance form shown in Figure 4.6. The form is divided into logically separate pages, with each page contained within an individual case element.
Figure 4.6 Using construct switch to navigate through a complex task.
< switch xmlns ="http://www.w3.org/2002/xforms" ref ="/insurance/policy-form"> < case id ="general"> < label >General Information</ label > < group ref ="general">...</ group > </ case > < case id ="coverage"> < label >Coverage</ label > < group ref ="coverage">...</ group > </ case > < case id ="fees"> < label >Annual Fees</ label > < group ref ="fees">...</ group > </ case > < case id ="summary"> < label >Summary</ label >...</ case > </ switch >
Notice that all (except the last) case elements use a group to establish the XPath evaluation context for relative XPath locators appearing within that group. The final case shows a summary of the information collected ”typically, such a summary displays key values collected by all of the earlier pages in the form. This summary uses the context set up by the containing switch for evaluating relative XPath locators.
As described earlier, navigation among the cases can be enabled by creating trigger controls that invoke handler toggle . Handler toggle achieves its effect by dispatching the appropriate events to the switch to change the case that is active.
Notice that this design enables XForms clients to enhance the end-user experience by binding platform-specific keys that navigate through the different case elements in a switch construct. For example, consider an XForms browser designed for use on a cell phone with forward and back navigation keys. Pressing these keys typically raises a platform-specific event; the XForms client for this platform can map these device-specific events to the corresponding XForms events to allow navigation through a multipage user interface created via construct switch .
4.2.5 Creating Wizards Using switch
User interface wizards aids in rapid task completion. The combination of interaction-based switching provided by construct switch can be combined with model-based switching via model property relevant in creating task-based wizards. Application-specific knowledge can be codified in the XForms model; thus, in an insurance form, the portion of the user interface pertaining to questions about an applicant 's children can be selectively revealed based on the user's response to an earlier question.
Binding attributes on the navigation controls used to move among the different case groupings in a switch construct can be used to ensure that the user does not leave a portion of the interface without providing critical items of information. As an example, consider a user interface that collects the necessary information before configuring the wireless network on a mobile device. This information might include authorization information such as a user id and password. Assume further that this task has been factored into a set of logically grouped pages to create a multipage dialog using construct switch (see Figure 4.7). The corresponding visual interface produced by X-Smiles is shown in Figure 4.8.
Figure 4.7 Task wizard authored using switch .
< html xmlns ="http://www.w3.org/1999/xhtml" xmlns:ev ="http://www.w3.org/2001/xml-events"> < head >< title >XForms Wizard</ title > < model xmlns ="http://www.w3.org/2002/xforms" xmlns:xsd ="http://www.w3.org/2001/XMLSchema" schema ="mobile.xsd"> < instance id ="m"> < auth xmlns ="">< id />< pin /></ auth > </ instance > < instance id ="s"> < data xmlns ="">< pin-check /></ data > </ instance > <!-- Used by wizard --> < bind nodeset ="instance('s')/pin-check" relevant = "string-length(instance('m')/id)>0 and string-length (instance('m')/pin)>0"/> </ model ></ head > < body > < switch xmlns ="http://www.w3.org/2002/xforms" ref ="/auth"> < case id ="auth">< label >Authorization</ label > < input ref ="id">...</ input > < secret ref ="pin">...</ secret > < trigger ref ="instance('s')/pin-check" ev:event ="DOMActivate"> < label >service details</ label > < toggle case ="service"/></ trigger ></ case > < case id ="service"> < label >Service</ label >...</ case > </ switch > </ body ></ html >
Figure 4.8. Visual representation of task wizard authored using switch .
The application author can ensure that the user provides the requisite information before moving off the authentication page by attaching an appropriate binding expression to the trigger that navigates from this page. In this example, the model contains a second instance that holds a state variable pin-check used for this purpose. This field itself does not collect a value; instead, it is used to enable or disable the navigation control that allows the user to move from the authorization page to the services page. Within the model, an XForms binding expression created via bind is used to bind model property relevant to instance('s')/pin-check . The value of this property, an XPath expression, is evaluated at run-time to return a boolean value. In this example, we have
relevant="length(instance('m')/pin)>0 and length(instance('m')/id)>0"
to specify that pin-check gets model property relevant=true if and only if the length of the value collected for instance('s')/pin is greater than 0. Within the user interface, control toggle in the case that collects authorization information binds to instance('m')/pin-check . As a consequence, this control becomes available to the user only if the /auth/id and /auth/pin values have been provided.
The functionality described here enhances end-user experience. The XForms model enables the application author to declare specific portions of the instance to be required , that is, the user may not submit the form until these required values have been provided. However, in the case of the multipage user interface rendered on a small device, ensuring that each page of the multipage task is correctly completed can often lead to more rapid task completion.
Finally, notice that this is the first example in this book to use the advanced XForms feature of having multiple instance elements in the model. Multiple instances are useful when an application needs to store temporary interaction state information that should not be submitted to the server. In this example, we have used element instance having id="m" to store the data to be transmitted to the server and element instance with attribute id="s" to hold interaction state. Access to multiple instances in the model is achieved via function instance described in Section 6.6. Model property relevant used in this example is described in Section 5.3.