# HG changeset patch # User paulb # Date 1202232331 0 # Node ID 185f79ad2450fe6538aefb3198e4fbe58d275ce1 # Parent 9a1e349e5701a38156dff6bd01762b279cc6f1d1 [project @ 2008-02-05 17:25:31 by paulb] Tidied formatting. diff -r 9a1e349e5701 -r 185f79ad2450 docs/multiple.html --- a/docs/multiple.html Sun Feb 03 22:44:31 2008 +0000 +++ b/docs/multiple.html Tue Feb 05 17:25:31 2008 +0000 @@ -6,48 +6,117 @@
Up to this point, we have only considered two kinds of Web form fields: text entry fields and action buttons. Since most Web forms offer more convenient ways of entering certain kinds of data, we shall now investigate multiple-choice fields as an example of how XSLForms handles more complicated types of fields.
+We shall revise our form data structure to be the following:
-<?xml version="1.0"?>+ +
<structure>
<item value="some value">
<type value="some type"/>
<subitem subvalue="some other value"/>
</item>
</structure>
<?xml version="1.0"?> +<structure> + <item value="some value"> + <type value="some type"/> + <subitem subvalue="some other value"/> + </item> +</structure>+
Whilst HTML offers types of form fields where users can select one or many values presented in a list or menu, we shall first consider the case where only a single value can be chosen from such a selection.
+ -From the item type list only one value may be selected. + +From the item type list only one value may be selected.
+Taking the example HTML code from before, we can add a definition of this new list to the template to produce something like this:
-<html xmlns="http://www.w3.org/1999/xhtml"+ +
xmlns:template="http://www.boddie.org.uk/ns/xmltools/template">
<head>
<title>Example</title>
</head>
<body template:element="structure">
<form action="" method="post">
<!-- Template text between the start and the interesting part. -->
<div template:element="item">
<p>
Some item: <input template:attribute-field="value" name="..." type="text" value="..." />
<input name="..." template:selector-field="remove" type="submit" value="Remove" />
</p>
<p>
Item type:
<select template:multiple-choice-field="type,value" name="...">
<option template:multiple-choice-value="type-enum,value,selected" value="..." />
</select>
</p>
<p>
Itself containing more items:
</p>
<p template:element="subitem">
Sub-item: <input template:attribute-field="subvalue" name="..." type="text" value="..." />
<input name="..." template:selector-field="remove2" type="submit" value="Remove" />
</p>
<p>
<input name="..." template:selector-field="add2,subitem" type="submit" value="Add subitem" />
</p>
</div>
<p>
<input name="..." template:selector-field="add,item" type="submit" value="Add item" />
</p>
<!-- Template text between the interesting part and the end. -->
</form>
</body>
</html>
+<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"> +<head> + <title>Example</title> +</head> +<body template:element="structure"> +<form action="" method="post"> + +<!-- Template text between the start and the interesting part. --> + +<div template:element="item"> + <p> + Some item: <input template:attribute-field="value" name="..." type="text" value="..." /> + <input name="..." template:selector-field="remove" type="submit" value="Remove" /> + </p> + <p> + Item type: + <select template:multiple-choice-field="type,value" name="..."> + <option template:multiple-choice-value="type-enum,value,selected" value="..." /> + </select> + </p> + <p> + Itself containing more items: + </p> + <p template:element="subitem"> + Sub-item: <input template:attribute-field="subvalue" name="..." type="text" value="..." /> + <input name="..." template:selector-field="remove2" type="submit" value="Remove" /> + </p> + <p> + <input name="..." template:selector-field="add2,subitem" type="submit" value="Add subitem" /> + </p> +</div> +<p> + <input name="..." template:selector-field="add,item" type="submit" value="Add item" /> +</p> + +<!-- Template text between the interesting part and the end. --> + +</form> +</body> +</html> ++
There are a lot of details here that need to be explained. Here is what was done:
+select
-element was added.select
element is mapped onto the type
-element in the form data structure, indicating using a special template:multiple-choice-field
attribute that the value
attribute of the type
-element will contain any chosen value from the list of values displayed in the page.template:multiple-choice-field
attribute that the
+ value
attribute of the type
element will
+ contain any chosen value from the list of values displayed in the page.
select
element, we include an option
-element which defines the values which will be presented to users
-of the form. Here, the special template:multiple-choice-value
attribute indicates that the option
element maps onto
-a type-enum
element which is not mentioned in our
-revised form data structure above; this will be discussed below.template:multiple-choice-value
+ attribute indicates that the option
element maps onto a
+ type-enum
element which is not mentioned in our revised
+ form data structure above; this will be discussed below.
Although we revised the form data structure above, and whilst the revised structure can describe form data submitted by users of our application, it is unfortunately not sufficient to define the form data @@ -55,28 +124,68 @@ be presented to users: such values are not defined in our revised structure. Therefore, we shall define an output form data structure as follows:
-<?xml version="1.0"?>+ +
<structure>
<item value="some value">
<type value="some type">
<type-enum value="choice #n"/>
</type>
<subitem subvalue="some other value"/>
</item>
</structure>
+<?xml version="1.0"?> +<structure> + <item value="some value"> + <type value="some type"> + <type-enum value="choice #n"/> + </type> + <subitem subvalue="some other value"/> + </item> +</structure> ++
In the template, the option
element is presented
using a number of special annotations which make more sense when
considering the above output structure:
template:multiple-choice-value
annotation states that the
option
element maps into the type-enum
-element, meaning that each type-enum
element will be
-reproduced as an option inside the list or menu presented in the Web
-form.type-enum
element will be
+ reproduced as an option inside the list or menu presented in the Web
+ form.
template:multiple-choice-value
annotation also states that the
-contents of the option
element will correspond to
-the value of the type-enum
element's value
-attribute.template:multiple-choice-value
annotation provides a final piece of information: the name of an attribute which will be created on the option
element if the element's value matches the enclosing select
element's value. This has the effect of making sure that the select
element always reveals the selected value in its list of values.
- value
attribute is set to a value which does not matter - it will be replaced in the final output.option
element will correspond to
+ the value of the type-enum
element's value
+ attribute.
+ template:multiple-choice-value
annotation provides
+ a final piece of information: the name of an attribute which will be
+ created on the option
element if the element's value
+ matches the enclosing select
element's value. This has
+ the effect of making sure that the select
element always
+ reveals the selected value in its list of values.value
attribute is set to a value which does not
+ matter - it will be replaced in the final output.The result of this is that the type
element in the
this example structure fragment...
<type value="2">+ +
<type-enum value="(Not selected)"/>
<type-enum value="Important"/>
<type-enum value="Not important"/>
<type-enum value="Personal"/>
</type>
+<type value="2"> + <type-enum value="(Not selected)"/> + <type-enum value="Important"/> + <type-enum value="Not important"/> + <type-enum value="Personal"/> +</type> ++
...is transformed into something resembling this HTML code:
-<select name="...">+ +
<option value="(Not selected)">(Not selected)</option>
<option value="Important" selected="selected">Important</option>
<option value="Not important">Not important</option>
<option value="Personal">Personal</option>
</select>
+<select name="..."> + <option value="(Not selected)">(Not selected)</option> + <option value="Important" selected="selected">Important</option> + <option value="Not important">Not important</option> + <option value="Personal">Personal</option> +</select> ++
Such presentation techniques are sufficient if the input form data structure is identical to the output structure, but since we will receive a structure resembling that defined @@ -85,50 +194,97 @@ will need to find a way of merging the range of allowed values into the user-edited form data before presenting that data using our template.
+There are many possible ways of inserting extra XML elements into an existing XML document, but XSLForms provides an easy way of defining lists of values that will be included in the way we desire. First, let us define a document containing all the possible values for the type field:
-<?xml version="1.0"?>+ +
<type>
<type-enum value="(Not selected)"/>
<type-enum value="Important"/>
<type-enum value="Not important"/>
<type-enum value="Personal"/>
</type>
+<?xml version="1.0"?> +<type> + <type-enum value="(Not selected)"/> + <type-enum value="Important"/> + <type-enum value="Not important"/> + <type-enum value="Personal"/> +</type> ++
We shall refer to this document when inserting the different type-enum
elements into our input form data structure to produce the output
structure described above; it can be
found in examples/Common/VerySimple/Resources/structure_types.xml
.
To take advantage of this new information, it is necessary to introduce some code into the Web resource to perform the document initialisation. The special WebStack resource that we subclassed earlier provides some convenient mechanisms for introducing XML documents and initialisations, and we shall add a few extra attributes to our resource class in order to take advantage of them:
-# Under template_resources...+ +
init_resources = {
"structure" : ("structure_template.xhtml", "structure_input.xsl")
}
document_resources = {
"types" : "structure_types.xml"
}
# Under template_resources... + + init_resources = { + "structure" : ("structure_template.xhtml", "structure_input.xsl") + } + document_resources = { + "types" : "structure_types.xml" + }+
These attributes define the following things:
+structure
which links
-the structure_template.xhtml
file (the template) to the structure_input.xsl
stylesheet file. This is very similar to the way the template_resources
dictionary links templates to other stylesheet files producing output.structure_template.xhtml
file (the template)
+ to the structure_input.xsl
stylesheet file. This
+ is very similar to the way the template_resources
+ dictionary links templates to other stylesheet files producing
+ output.
types
which
-is provided by the structure_types.xml
file.structure_types.xml
file.
To actually perform the initalisation or merge operation, we need to add a few extra
lines of code after the addition and deletion operations in the respond_to_form
method:
# Under the addition and deletion operations...+ +
# Initialise the document, adding enumerations/ranges.
structure_xsl = self.prepare_initialiser("structure")
types_xml = self.prepare_document("types")
structure = self.get_result([structure_xsl], structure, references={"type" : types_xml})
# Start the response.
+ # Under the addition and deletion operations... + + # Initialise the document, adding enumerations/ranges. + + structure_xsl = self.prepare_initialiser("structure") + types_xml = self.prepare_document("types") + structure = self.get_result([structure_xsl], structure, references={"type" : types_xml}) + + # Start the response. ++
These lines do the following things:
+structure
initialisation.types
document containing the
-values to be merged into the form data.structure
,
-using a reference to the types
document containing
-the values.types
document containing
+ the values.
The result of this should be a processed structure
document containing the type values for each type
element in that document.
We have now added a simple, single-valued multiple-choice field to the application. However, many applications often need to obtain multivalued multiple-choice data, and this kind of information is investigated in the next part of the development process.
-