# HG changeset patch # User paulb # Date 1121882382 0 # Node ID 41d16ed58fc7ba6e86136af70f99aa95bf05cd4c # Parent fce8d5e7a1f4052f57b26cce9169e4c38912f1c9 [project @ 2005-07-20 17:59:42 by paulb] Added a more complete description of introducing multiple-choice fields into applications. diff -r fce8d5e7a1f4 -r 41d16ed58fc7 docs/multiple.html --- a/docs/multiple.html Wed Jul 20 17:02:18 2005 +0000 +++ b/docs/multiple.html Wed Jul 20 17:59:42 2005 +0000 @@ -78,9 +78,130 @@ 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>
-

But since we will receive a structure resembling that defined -earlier, yet need to present a structure like the one above, we will +

Presenting the Extra Values

+

In the template, the option element is presented +using a number of special annotations which make more sense when +considering the above output structure:

+ +

The result of this is that the type element in the +this example structure fragment...

+
<type value="2">
<type-enum value="1"/>
<type-enum value="2"/>
<type-enum value="3"/>
</type>
+

...is transformed into something resembling this HTML code:

+
<select name="...">
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</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 +earlier (where the multiple-choice values are never sent back to the +application), yet need to present a structure like the one above, we +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.

+

Merging Values into the Form Data

+

There are many possible ways of inserting extra XML elements into an +existing XML document, but we shall concentrate on using an XSL +stylesheet to perform this merge operation. First, let us define a +document containing all the possible values for the type field:

+
<?xml version="1.0"?>
<types>
<type-enum value="(Not selected)"/>
<type-enum value="Important"/>
<type-enum value="Not important"/>
<type-enum value="Personal"/>
</types>
+

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. The stylesheet which performs this task is +quite scary for those not familiar with XSL, but it works on the +following principles:

+
    +
  1. Descend into the form data structure, copying all elements, +attributes and text that the stylesheet is not programmed to recognise.
  2. +
  3. When encountering an item element (which the +stylesheet is programmed to recognise), do the following:
    +
      +
    1. Copy the element "skeleton" and its attributes so that +the value attribute is retained.
    2. +
    3. Look for a type element inside the item +element.
    4. +
    5. Where a type element exists, process +it; otherwise, make a new type element and process +that.
    6. +
    +
  4. +
  5. When encountering an existing type element, do +the following:
    +
      +
    1. Copy the element "skeleton" and its attributes so that +the value attribute is retained.
    2. +
    3. Add the type-enum elements from the +document defined above.
    4. +
    +
  6. +
  7. When processing a new type element, do the +following:
    +
      +
    1. Add the type-enum elements from the +document defined above.
    2. +
    +
  8. +
+

The stylesheet source code can be found in examples/Common/VerySimple/Resources/structure_types.xsl, +whereas the document defined above which contains the values can be +found in examples/Common/VerySimple/Resources/structure_types.xml.

+

Performing the Merge

+

To take advantage of these new documents, it is necessary to +introduce some code into the Web resource to perform the merge +operation. The special WebStack resource that we subclassed earlier provides some +convenient mechanisms for introducing XSL-based transformations, and we +shall add a few extra attributes to our resource class in order to take +advantage of them:

+
    # Under template_resources...

transform_resources = {
"types" : ["structure_types.xsl"]
}
document_resources = {
"types" : "structure_types.xml"
}
+

These attributes define the following things:

+
    +
  1. A transformation called types which uses +the structure_types.xsl stylesheet file.
  2. +
  3. A document referred to by the name types which +is provided by the structure_types.xml file.
  4. +
+

To actually perform the 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...

# Transform, adding enumerations/ranges.

types_xsl_list = self.prepare_transform("types")
types_xml = self.prepare_document("types")
structure = self.get_result(types_xsl_list, structure, references={"types" : types_xml})

# Start the response.
+

These lines do the following things:

+
    +
  1. Obtain the stylesheets for the types +transformation.
  2. +
  3. Obtain the types document containing the +values to be merged into the form data.
  4. +
  5. Take the stylesheets and apply them to the form data, structure, +using a reference to the types document containing +the values.
  6. +
+

The result of this should be a processed structure +document containing the type values for each type +element in that document.

+

Other Multiple-Choice Data

+

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.