- From: Mark Birbeck <mark.birbeck@x-port.net>
- Date: Wed, 18 Aug 2004 21:35:51 +0100
- To: "'Andrew MacDonald'" <andrew_james_macdonald@yahoo.com>
- Cc: <www-forms@w3.org>
Andrew, > Is there a way in XForms to produce the equivalent to > the following HTML? [snip] I tried to do something similar > in XForms, but discovered that placing input elements within > item elements isn't allowed.Is there an alternate way to do > this? As it happens, HTML doesn't actually support what you want. First, you can't nest <input> controls - in HTML there is no closing tag for <input>, and in XHTML <input> is defined as being empty. Also, the behaviour of radio buttons is only in relation to the submission of data, not to interaction with other controls, so even if you 'un-nest' the controls, the relationship between them (that one control is used to indicate a choice amongst one or other controls) would have to be defined with script. The good news is though, that XForms *does* support this - these are exactly the types of scenarios that the language set out to solve without using spaghetti script. And there are actually a number of ways to do what you want, depending on whether you are simply manipulating the user interface, or whether you are making decisions in the flow of form-filling based on other data in the form. The technique that is usually the easiest to understand is the use of switch and case. Here only one section of the form - from amongst a number of mutually exclusive alternatives - is 'active' at any time. Exactly which section is active is dictated by the use of a toggle instruction. An illustration of using this is given here: <http://www.formsplayer.com/demo/switch-case/print-settings.html> It's aimed at formsPlayer, but should work in other XForms processors. You can read the source if you don't want to install anything. One of the disadvantages of this technique though, is that you have to mark-up the conditions under which your toggles will be used to select from amongst the sections. And it gets even more complicated if you actually want a number of 'active' sections, based on information that your user has already provided. A much more powerful technique is to use what we call 'model-based switching' - essentially leaving the activation and de-activation of your controls to the XForms processor, based on conditions that you specify. This is achieved with the 'relevant' model-item property (MIP). In effect you are saying that some node is 'active' if some condition is met, and is not active otherwise. Any controls that are bound to that node will automatically get notified by the processor, as the node changes state. An example of this is given in the XForms test suite: <http://www.w3.org/MarkUp/Forms/Test/chapter6/relevant.xml> If you are running formsPlayer then a converted version of the form with the <object> tags in, is available here: <http://www.formsplayer.com/TestSuite/chapter6/relevant.html> As you can see, a node 'health' in the instance data is 'relevant' only if some other node (called 'is-senior') is set to true: <bind nodeset="health" relevant="boolean-from-string(../is-senior) = true()" /> With this single statement *any* control that uses 'health' will have its CSS state automatically set by the processor, based on the calculation. In the form we're looking at here, it's actually a <group> that relies on the data: <group ref="health"> <label>Health Matters</label> <input ref="heart"> <label>Heart Condition</label> </input> <range ref="bp/diastolic" start="0" end="300"> <label>Diastolic Blood Pressure</label> </range> <range ref="bp/systolic" start="0" end="300"> <label>Systolic Blood Pressure</label> </range> </group> So, to complete the picture, all that is needed is a CSS rule that hides the display of any control that is bound to a node that is 'not relevant'. This is defined as follows: *::disabled { display: none; } (If you are using formsPlayer then use .disabled instead of ::disabled.) Now this entire group of controls will become hidden if the user fills in a control that indicates they are not a senior citizen (and reappear again if the form filler ages quickly). Note that this same technique can be used to build a wizard-style form in a just a few lines of mark-up: <http://www.formsplayer.com/demo/wizard/model-based-switching.htm> Note that normally quite complex constructs such as "don't show the [NEXT] or [PREV] button if we are at the end or beginning of the list" are easily constructed using the above technique on <trigger>s. Regards, Mark Mark Birbeck CEO x-port.net Ltd. e: Mark.Birbeck@x-port.net t: +44 (0) 20 7689 9232 w: http://www.formsPlayer.com/ Download our XForms processor from http://www.formsPlayer.com/
Received on Wednesday, 18 August 2004 20:36:01 UTC