1 <?xml version="1.0" encoding="iso-8859-1"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3 <html xmlns="http://www.w3.org/1999/xhtml"><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 <link href="styles.css" rel="stylesheet" type="text/css" /></head> 7 <body> 8 <h1>Creating Applications: Adding Multiple-Choice Fields and Values</h1> 9 10 <p>Up to this point, we have only considered two kinds of Web form 11 fields: text entry fields and action buttons. Since most Web forms 12 offer more convenient ways of entering certain kinds of data, we shall 13 now investigate multiple-choice fields as an example of how XSLForms 14 handles more complicated types of fields.</p> 15 16 <p>We shall revise our <a href="data.html">form data structure</a> to 17 be the following:</p> 18 19 <pre><?xml version="1.0"?> 20 <structure> 21 <item value="some value"> 22 <type value="some type"/> 23 <subitem subvalue="some other value"/> 24 </item> 25 </structure></pre> 26 27 <h2>Single-Valued Fields</h2> 28 29 <p>Whilst HTML offers types of form fields where users can select one 30 or many values presented in a list or menu, we shall first consider the 31 case where only a single value can be chosen from such a selection.</p> 32 33 <form method="post" action="" name="single"> 34 <p>Some item: <input name="value" value="some value" /><input name="remove" value="Remove" type="submit" /></p> 35 <p>Item type: 36 <select name="type"> 37 <option>(Not selected)</option> 38 <option>Important</option> 39 <option>Not important</option> 40 <option>Personal</option> 41 </select> 42 </p> 43 <p>Itself containing more items:</p> 44 <p>Sub-item: <input name="subvalue" value="some other value" /><input name="remove2" value="Remove" type="submit" /></p> 45 </form> 46 47 <p>From the item type list only one value may be selected.</p> 48 49 <p>Taking the example HTML code from before, we can add a 50 definition of this new list to the template to produce something 51 like this:</p> 52 53 <pre> 54 <html xmlns="http://www.w3.org/1999/xhtml" 55 xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"> 56 <head> 57 <title>Example</title> 58 </head> 59 <body template:element="structure"> 60 <form action="" method="post"> 61 62 <!-- Template text between the start and the interesting part. --> 63 64 <div template:element="item"> 65 <p> 66 Some item: <input template:attribute-field="value" name="..." type="text" value="..." /> 67 <input name="..." template:selector-field="remove" type="submit" value="Remove" /> 68 </p> 69 <span style="font-weight: bold;"><p></span> 70 <span style="font-weight: bold;">Item type:</span> 71 <span style="font-weight: bold;"><select template:multiple-choice-field="type,value" name="..."></span> 72 <span style="font-weight: bold;"><option template:multiple-choice-value="type-enum,value,selected" value="..." /></span> 73 <span style="font-weight: bold;"></select></span> 74 <span style="font-weight: bold;"></p></span> 75 <p> 76 Itself containing more items: 77 </p> 78 <p template:element="subitem"> 79 Sub-item: <input template:attribute-field="subvalue" name="..." type="text" value="..." /> 80 <input name="..." template:selector-field="remove2" type="submit" value="Remove" /> 81 </p> 82 <p> 83 <input name="..." template:selector-field="add2,subitem" type="submit" value="Add subitem" /> 84 </p> 85 </div> 86 <p> 87 <input name="..." template:selector-field="add,item" type="submit" value="Add item" /> 88 </p> 89 90 <!-- Template text between the interesting part and the end. --> 91 92 </form> 93 </body> 94 </html> 95 </pre> 96 97 <p>There are a lot of details here that need to be explained. Here is 98 what was done:</p> 99 100 <ol> 101 <li>A paragraph was added to provide some space on the page for the 102 field.</li> 103 <li>Inside the paragraph, next to the label text, an HTML <code>select</code> 104 element was added.</li> 105 <li>The <code>select</code> element is mapped onto the <code>type</code> 106 element in the form data structure, indicating using a special 107 <code>template:multiple-choice-field</code> attribute that the 108 <code>value</code> attribute of the <code>type</code> element will 109 contain any chosen value from the list of values displayed in the page.</li> 110 <li>Inside the <code>select</code> element, we include an <code>option</code> 111 element which defines the values which will be presented to users 112 of the form. Here, the special <code>template:multiple-choice-value</code> 113 attribute indicates that the <code>option</code> element maps onto a 114 <code>type-enum</code> element which is not mentioned in our revised 115 form data structure above; this will be discussed below.</li> 116 </ol> 117 118 <h2>Output Structures</h2> 119 120 <p>Although we revised the form data structure above, and whilst the 121 revised structure can describe form data submitted by users of our 122 application, it is unfortunately not sufficient to define the form data 123 that is to be presented. Consider the multiple-choice values that shall 124 be presented to users: such values are not defined in our revised 125 structure. Therefore, we shall define an output form data structure as 126 follows:</p> 127 128 <pre> 129 <?xml version="1.0"?> 130 <structure> 131 <item value="some value"> 132 <type value="some type"> 133 <type-enum value="choice #n"/> 134 </type> 135 <subitem subvalue="some other value"/> 136 </item> 137 </structure> 138 </pre> 139 140 <h3>Presenting the Extra Values</h3> 141 142 <p>In the template, the <code>option</code> element is presented 143 using a number of special annotations which make more sense when 144 considering the above output structure:</p> 145 146 <ul> 147 <li>The <code>template:multiple-choice-value</code> annotation states that the 148 <code>option</code> element maps into the <code>type-enum</code> 149 element, meaning that each <code>type-enum</code> element will be 150 reproduced as an option inside the list or menu presented in the Web 151 form.</li> 152 <li>The <code>template:multiple-choice-value</code> annotation also states that the 153 contents of the <code>option</code> element will correspond to 154 the value of the <code>type-enum</code> element's <code>value</code> 155 attribute.</li> 156 <li>The <code>template:multiple-choice-value</code> annotation provides 157 a final piece of information: the name of an attribute which will be 158 created on the <code>option</code> element if the element's value 159 matches the enclosing <code>select</code> element's value. This has 160 the effect of making sure that the <code>select</code> element always 161 reveals the selected value in its list of values.</li> 162 <li>The <code>value</code> attribute is set to a value which does not 163 matter - it will be replaced in the final output.</li> 164 </ul> 165 166 <p>The result of this is that the <code>type</code> element in the 167 this example structure fragment...</p> 168 169 <pre> 170 <type value="2"> 171 <type-enum value="(Not selected)"/> 172 <type-enum value="Important"/> 173 <type-enum value="Not important"/> 174 <type-enum value="Personal"/> 175 </type> 176 </pre> 177 178 <p>...is transformed into something resembling this HTML code:</p> 179 180 <pre> 181 <select name="..."> 182 <option value="(Not selected)">(Not selected)</option> 183 <option value="Important" selected="selected">Important</option> 184 <option value="Not important">Not important</option> 185 <option value="Personal">Personal</option> 186 </select> 187 </pre> 188 189 <p>Such presentation techniques are sufficient if the input form data 190 structure is identical to the output structure, but since we will 191 receive a structure resembling that defined 192 earlier (where the multiple-choice values are never sent back to the 193 application), yet need to present a structure like the one above, we 194 will 195 need to find a way of merging the range of allowed values into the 196 user-edited form data before presenting that data using our template.</p> 197 198 <h2><a name="DocumentInitialisation"></a>Document Initialisation</h2> 199 200 <p>There are many possible ways of inserting extra XML elements into an 201 existing XML document, but XSLForms provides an easy way of defining 202 lists of values that will be included in the way we desire. First, let 203 us define a 204 document containing all the possible values for the type field:</p> 205 206 <pre> 207 <?xml version="1.0"?> 208 <type> 209 <type-enum value="(Not selected)"/> 210 <type-enum value="Important"/> 211 <type-enum value="Not important"/> 212 <type-enum value="Personal"/> 213 </type> 214 </pre> 215 216 <p>We shall refer to this document when inserting the different <code>type-enum</code> 217 elements into our input form data structure to produce the output 218 structure described above; it can be 219 found in <code>examples/Common/VerySimple/Resources/structure_types.xml</code>.</p> 220 221 <h3>Amending the Resource</h3> 222 223 <p>To take advantage of this new information, it is necessary to 224 introduce some code into the Web resource to perform the document initialisation. The special WebStack resource that we <a href="Web-resource.html">subclassed earlier</a> provides some 225 convenient mechanisms for introducing XML documents and initialisations, and we 226 shall add a few extra attributes to our resource class in order to take 227 advantage of them:</p> 228 229 <pre> # Under template_resources... 230 231 init_resources = { 232 "structure" : ("structure_template.xhtml", "structure_input.xsl") 233 } 234 document_resources = { 235 "types" : "structure_types.xml" 236 }</pre> 237 238 <p>These attributes define the following things:</p> 239 240 <ol> 241 <li>A initialisation called <code>structure</code> which links 242 the <code>structure_template.xhtml</code> file (the template) 243 to the <code>structure_input.xsl</code> stylesheet file. This 244 is very similar to the way the <code>template_resources</code> 245 dictionary links templates to other stylesheet files producing 246 output.</li> 247 <li>A document referred to by the name <code>types</code> which 248 is provided by the <code>structure_types.xml</code> file.</li> 249 </ol> 250 251 <p>To actually perform the initalisation or merge operation, we need to add a few extra 252 lines of code after the addition and deletion operations in the <code>respond_to_form</code> 253 method:</p> 254 255 <pre> 256 # Under the addition and deletion operations... 257 258 # Initialise the document, adding enumerations/ranges. 259 260 structure_xsl = self.prepare_initialiser("structure") 261 types_xml = self.prepare_document("types") 262 structure = self.get_result([structure_xsl], structure, references={"type" : types_xml}) 263 264 # Start the response. 265 </pre> 266 267 <p>These lines do the following things:</p> 268 269 <ol> 270 <li>Obtain the stylesheet for the <code>structure</code> initialisation.</li> 271 <li>Obtain the <code>types</code> document containing the 272 values to be merged into the form data.</li> 273 <li>Take the stylesheet and apply it to the form data, <code>structure</code>, 274 using a reference to the <code>types</code> document containing 275 the values.</li> 276 </ol> 277 278 <p>The result of this should be a processed <code>structure</code> 279 document containing the type values for each <code>type-enum</code> 280 element in that document found under the <code>type</code> element 281 (as specified in the <code>template:multiple-choice-field</code> 282 attribute).</p> 283 284 <h3>Specifying a Context Element</h3> 285 286 <p>Note that the feature of <code>template:multiple-choice-field</code> 287 where the context element is specified as <code>-</code>, meaning the 288 element on which the attribute for the field will be found, has 289 implications for the naming of the root element in the document 290 providing the values for a multiple-choice field: such elements need 291 to be named after this context element, and it is frequently less 292 inconvenient (and more obvious) to explicitly state a context element 293 instead of adopting the name of the current element from the template. 294 One situation where the current element might be more convenient as 295 the context element is where many multiple-choice fields are to be 296 supplied by the same document containing each range of values for all 297 the different fields.</p> 298 299 <h2>Other Multiple-Choice Data</h2> 300 301 <p>We have now added a simple, single-valued multiple-choice field to 302 the application. However, many applications often need to obtain <a href="multivalue.html">multivalued multiple-choice data</a>, and this 303 kind of information is investigated in the next part of the development 304 <a href="overview.html">process</a>.</p> 305 306 </body> 307 </html>