XSLTools

docs/multiple.html

211:a4006b6da1a0
2005-08-25 paulb [project @ 2005-08-25 14:43:34 by paulb] Changed the path encoding to UTF-8 - if this is not correct, ISO-8859-1 will be tried anyway.
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">     2 <html xmlns="http://www.w3.org/1999/xhtml">     3 <head>     4   <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" />     5   <title>Creating Applications: Adding Multiple-Choice Fields and Values</title>     6   <meta name="generator"     7  content="amaya 8.1a, see http://www.w3.org/Amaya/" />     8   <link href="styles.css" rel="stylesheet" type="text/css" />     9 </head>    10 <body>    11 <h1>Creating Applications: Adding Multiple-Choice Fields and Values</h1>    12 <p>Up to this point, we have only considered two kinds of Web form    13 fields: text entry fields and action buttons. Since most Web forms    14 offer more convenient ways of entering certain kinds of data, we shall    15 now investigate multiple-choice fields as an example of how XSLForms    16 handles more complicated types of fields.</p>    17 <p>We shall revise our <a href="data.html">form data structure</a> to    18 be the following:</p>    19 <pre>&lt;?xml version="1.0"?&gt;<br />&lt;structure&gt;<br />  &lt;item value="some value"&gt;<br />    &lt;type value="some type"/&gt;<br />    &lt;subitem subvalue="some other value"/&gt;<br />  &lt;/item&gt;<br />&lt;/structure&gt;</pre>    20 <h2>Single-Valued Fields</h2>    21 <p>Whilst HTML offers types of form fields where users can select one    22 or many values presented in a list or menu, we shall first consider the    23 case where only a single value can be chosen from such a selection.</p>    24 <form method="post" action="" name="single">    25   <p>Some item:&nbsp;<input name="value" value="some value" /><input    26  name="remove" value="Remove" type="submit" /></p>    27   <p>Item type:    28   <select name="type">    29   <option>(Not selected)</option>    30   <option>Important</option>    31   <option>Not important</option>    32   <option>Personal</option>    33   </select>    34   </p>    35   <p>Itself containing more items:</p>    36   <p>Sub-item: <input name="subvalue" value="some other value" /><input    37  name="remove2" value="Remove" type="submit" /></p>    38 </form>    39 From the&nbsp;item type list only one value may be selected.    40 <p>Taking the&nbsp;example HTML code from before, we can add a    41 definition of this new list to the template to produce something    42 like this:</p>    43 <pre>&lt;html xmlns="http://www.w3.org/1999/xhtml"<br />      xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"&gt;<br />&lt;head&gt;<br />  &lt;title&gt;Example&lt;/title&gt;<br />&lt;/head&gt;<br />&lt;body template:element="structure"&gt;<br />&lt;form action="" method="POST"&gt;<br /><br />&lt;!-- Template text between the start and the interesting part. --&gt;<br /><br />&lt;div template:element="item"&gt;<br />  &lt;p&gt;<br />    Some item: &lt;input template:attribute="value" name="{template:this-attribute()}" type="text" value="{$this-value}" /&gt;<br />    &lt;input name="remove={template:this-element()}" type="submit" value="Remove" /&gt;<br />  &lt;/p&gt;<br />  <span    44  style="font-weight: bold;">&lt;p&gt;</span><br    45  style="font-weight: bold;" /><span style="font-weight: bold;">    Item type:</span><br    46  style="font-weight: bold;" /><span style="font-weight: bold;">    &lt;select template:element="type" name="{template:new-attribute('value')}"&gt;</span><br    47  style="font-weight: bold;" /><span style="font-weight: bold;">      &lt;option template:element="type-enum" template:expr="@value = ../@value" template:expr-attr="selected"</span><br    48  style="font-weight: bold;" /><span style="font-weight: bold;">        template:value="@value" value="{@value}" /&gt;</span><br    49  style="font-weight: bold;" /><span style="font-weight: bold;">    &lt;/select&gt;</span><br    50  style="font-weight: bold;" /><span style="font-weight: bold;">  &lt;/p&gt;</span><br />  &lt;p&gt;<br />    Itself containing more items:<br />  &lt;/p&gt;<br />  &lt;p template:element="subitem"&gt;<br />    Sub-item: &lt;input template:attribute="subvalue" name="{template:this-attribute()}" type="text" value="{$this-value}" /&gt;<br />    &lt;input name="remove2={template:this-element()}" type="submit" value="Remove" /&gt;<br />  &lt;/p&gt;<br />  &lt;p&gt;<br />    &lt;input name="add2={template:this-element()}" type="submit" value="Add subitem" /&gt;<br />  &lt;/p&gt;<br />&lt;/div&gt;<br />&lt;p&gt;<br />  &lt;input name="add={template:this-element()}" type="submit" value="Add item" /&gt;<br />&lt;/p&gt;<span    51  style="font-weight: bold;"><br /><br /></span>&lt;!-- Template text between the interesting part and the end. --&gt;<br /><br />&lt;/form&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</pre>    52 <p>There are a lot of details here that need to be explained. Here is    53 what was done:</p>    54 <ol>    55   <li>A paragraph was added to provide some space on the page for the    56 field.</li>    57   <li>Inside the paragraph, next to the label text, an HTML&nbsp;<code>select</code>    58 element was added.</li>    59   <li>The&nbsp;<code>select</code> element is mapped onto the&nbsp;<code>type</code>    60 element in the form data structure. However, HTML fields must produce    61 values and it makes no sense to interpret a textual value as an    62 element. Therefore, we indicate in the name of the&nbsp;<code>select</code>    63 element that the value submitted maps onto the&nbsp;<code>value</code>    64 attribute of the&nbsp;<code>type</code> element in the form data    65 structure.</li>    66   <li>Inside the&nbsp;<code>select</code> element, we include an&nbsp;<code>option</code>    67 element which&nbsp;defines the values which will be presented to users    68 of the form. Note that the&nbsp;<code>option</code> element maps onto    69 a&nbsp;<code>type-enum</code> element which is not mentioned in our    70 revised form data structure above; this will be discussed below.</li>    71 </ol>    72 <h2>Output Structures</h2>    73 <p>Although we revised the form data structure above, and whilst the    74 revised structure can describe form data submitted by users of our    75 application, it is unfortunately not sufficient to define the form data    76 that is to be presented. Consider the multiple-choice values that shall    77 be presented to users: such values are not defined in our revised    78 structure. Therefore, we shall define an output form data structure as    79 follows:</p>    80 <pre>&lt;?xml version="1.0"?&gt;<br />&lt;structure&gt;<br />  &lt;item value="some value"&gt;<br />    &lt;type value="some type"&gt;<br />      &lt;type-enum value="choice #n"/&gt;<br />    &lt;/type&gt;<br />    &lt;subitem subvalue="some other value"/&gt;<br />  &lt;/item&gt;<br />&lt;/structure&gt;</pre>    81 <h3>Presenting the Extra Values</h3>    82 <p>In the template, the&nbsp;<code>option</code> element is presented    83 using a number of special annotations which make more sense when    84 considering the above output structure:</p>    85 <ul>    86   <li>The&nbsp;<code>template:element</code> annotation states that the    87     <code>option</code> element maps into the&nbsp;<code>type-enum</code>    88 element, meaning that each&nbsp;<code>type-enum</code> element will be    89 reproduced as an option inside the list or menu presented in the Web    90 form.</li>    91   <li>The&nbsp;<code>template:value</code> annotation states that the    92 contents of&nbsp;the <code>option</code> element will correspond to    93 the value of the&nbsp;<code>type-enum</code> element's&nbsp;<code>value</code>    94 attribute - the notation employed here actually belongs to XSL.</li>    95   <li>The&nbsp;<code>template:expr</code> and&nbsp;<code>template:expr-attr</code>    96 annotations work together and state that...<br />    97     <ol>    98       <li>When the expression in <code>template:expr</code> is true...</li>    99       <li>The attribute in <code>template:expr-attr</code> will be   100 added to the <code>option</code> element with a value identical to its   101 name.</li>   102     </ol>   103   </li>   104   <li>The <code>value</code> attribute is defined to reproduce   105 the&nbsp;<code>value</code> attribute from the&nbsp;<code>type-enum</code>   106 element - the notation employed here belongs, once again, to XSL.</li>   107 </ul>   108 <p>The result of this is that the&nbsp;<code>type</code> element in the   109 this example&nbsp;structure fragment...</p>   110 <pre>&lt;type value="2"&gt;<br />  &lt;type-enum value="1"/&gt;<br />  &lt;type-enum value="2"/&gt;<br />  &lt;type-enum value="3"/&gt;<br />&lt;/type&gt;</pre>   111 <p>...is transformed into something resembling this HTML code:</p>   112 <pre>&lt;select name="..."&gt;<br />  &lt;option value="1"&gt;1&lt;/option&gt;<br />  &lt;option value="2" selected="selected"&gt;2&lt;/option&gt;<br />  &lt;option value="3"&gt;3&lt;/option&gt;<br />&lt;/select&gt;</pre>   113 <p>Such presentation techniques are sufficient if the input form data   114 structure is identical to the output structure, but since we will   115 receive a structure resembling that defined   116 earlier (where the multiple-choice values are never sent back to the   117 application), yet need to present a structure like the one above, we   118 will   119 need to find a way of merging the range of allowed values into the   120 user-edited form data before presenting that data using our template.</p>   121 <h2>Merging Values into the Form Data</h2>   122 <p>There are many possible ways of inserting extra XML elements into an   123 existing XML document, but we shall concentrate on using an XSL   124 stylesheet to perform this merge operation. First, let us define a   125 document containing all the possible values for the type field:</p>   126 <pre>&lt;?xml version="1.0"?&gt;<br />&lt;types&gt;<br />  &lt;type-enum value="(Not selected)"/&gt;<br />  &lt;type-enum value="Important"/&gt;<br />  &lt;type-enum value="Not important"/&gt;<br />  &lt;type-enum value="Personal"/&gt;<br />&lt;/types&gt;</pre>   127 <p>We shall refer to this document when inserting the different&nbsp;<code>type-enum</code>   128 elements into our input form data structure to produce the output   129 structure described above. The stylesheet which performs this task is   130 quite scary for those not familiar with XSL, but it works on the   131 following principles:</p>   132 <ol>   133   <li>Descend into the form data structure, copying all elements,   134 attributes and text that the stylesheet is not programmed to recognise.</li>   135   <li>When encountering an&nbsp;<code>item</code> element (which the   136 stylesheet is programmed to recognise), do the following:<br />   137     <ol>   138       <li>Copy the&nbsp;element "skeleton" and its attributes so that   139 the&nbsp;<code>value</code> attribute is retained.</li>   140       <li>Make&nbsp;a&nbsp;<code>type</code> element inside the&nbsp;<code>item</code>   141 element and process it.</li>   142     </ol>   143   </li>   144   <li>When processing a new&nbsp;<code>type</code> element, do the   145 following:<br />   146     <ol>   147       <li>Copy the attributes of any existing&nbsp;<code>type</code>   148 element so that   149 the&nbsp;<code>value</code> attribute is retained.</li>   150       <li>Add the&nbsp;<code>type-enum</code> elements from the   151 document defined above.</li>   152     </ol>   153   </li>   154 </ol>   155 <p>The stylesheet source code can be found in&nbsp;<code>examples/Common/VerySimple/Resources/structure_types.xsl</code>,   156 whereas the document defined above which contains the values can be   157 found in <code>examples/Common/VerySimple/Resources/structure_types.xml</code>.</p>   158 <h3>Performing the Merge</h3>   159 <p>To take advantage of these new documents, it is necessary to   160 introduce some code into the Web resource to perform the merge   161 operation. The special WebStack resource that we <a   162  href="Web-resource.html">subclassed earlier</a> provides some   163 convenient mechanisms for introducing XSL-based transformations, and we   164 shall add a few extra attributes to our resource class in order to take   165 advantage of them:</p>   166 <pre>    # Under template_resources...<br /><br />    transform_resources = {<br />        "types" : ["structure_types.xsl"]<br />        }<br />    document_resources = {<br />        "types" : "structure_types.xml"<br />        }</pre>   167 <p>These attributes define the following things:</p>   168 <ol>   169   <li>A transformation called&nbsp;<code>types</code> which uses   170 the&nbsp;<code>structure_types.xsl</code> stylesheet file.</li>   171   <li>A document referred to by the name&nbsp;<code>types</code> which   172 is provided by the&nbsp;<code>structure_types.xml</code> file.</li>   173 </ol>   174 <p>To actually perform the merge operation, we need to add a few extra   175 lines of code after the addition and deletion operations in the&nbsp;<code>respond_to_form</code>   176 method:</p>   177 <pre>        # Under the addition and deletion operations...<br /><br />        # Transform, adding enumerations/ranges.<br /><br />        types_xsl_list = self.prepare_transform("types")<br />        types_xml = self.prepare_document("types")<br />        structure = self.get_result(types_xsl_list, structure, references={"types" : types_xml})<br /><br />        # Start the response.</pre>   178 <p>These lines do the following things:</p>   179 <ol>   180   <li>Obtain the stylesheets for the&nbsp;<code>types</code>   181 transformation.</li>   182   <li>Obtain the&nbsp;<code>types</code>&nbsp;document containing the   183 values to be merged into the form data.</li>   184   <li>Take the stylesheets and apply them to the form data,&nbsp;<code>structure</code>,   185 using a reference to the&nbsp;<code>types</code> document containing   186 the values.</li>   187 </ol>   188 <p>The result of this should be a processed&nbsp;<code>structure</code>   189 document containing the type values for each&nbsp;<code>type</code>   190 element in that document.</p>   191 <h2>Other Multiple-Choice Data</h2>   192 <p>We have now added a simple, single-valued multiple-choice field to   193 the application. However, many applications often need to obtain <a   194  href="multivalue.html">multivalued multiple-choice data</a>, and this   195 kind of information is investigated in the next part of the development   196 <a href="overview.html">process</a>.</p>   197 </body>   198 </html>