paulb@615 | 1 | <?xml version="1.0" encoding="iso-8859-1"?> |
paulb@141 | 2 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
paulb@270 | 3 | <html xmlns="http://www.w3.org/1999/xhtml"><head> |
paulb@141 | 4 | <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" /> |
paulb@615 | 5 | <title>Creating Applications: Adding Multiple-Choice Fields and Values</title> |
paulb@270 | 6 | <link href="styles.css" rel="stylesheet" type="text/css" /></head> |
paulb@141 | 7 | <body> |
paulb@141 | 8 | <h1>Creating Applications: Adding Multiple-Choice Fields and Values</h1> |
paulb@141 | 9 | <p>Up to this point, we have only considered two kinds of Web form |
paulb@141 | 10 | fields: text entry fields and action buttons. Since most Web forms |
paulb@141 | 11 | offer more convenient ways of entering certain kinds of data, we shall |
paulb@141 | 12 | now investigate multiple-choice fields as an example of how XSLForms |
paulb@141 | 13 | handles more complicated types of fields.</p> |
paulb@141 | 14 | <p>We shall revise our <a href="data.html">form data structure</a> to |
paulb@141 | 15 | be the following:</p> |
paulb@141 | 16 | <pre><?xml version="1.0"?><br /><structure><br /> <item value="some value"><br /> <type value="some type"/><br /> <subitem subvalue="some other value"/><br /> </item><br /></structure></pre> |
paulb@141 | 17 | <h2>Single-Valued Fields</h2> |
paulb@141 | 18 | <p>Whilst HTML offers types of form fields where users can select one |
paulb@141 | 19 | or many values presented in a list or menu, we shall first consider the |
paulb@141 | 20 | case where only a single value can be chosen from such a selection.</p> |
paulb@145 | 21 | <form method="post" action="" name="single"> |
paulb@615 | 22 | <p>Some item: <input name="value" value="some value" /><input name="remove" value="Remove" type="submit" /></p> |
paulb@141 | 23 | <p>Item type: |
paulb@270 | 24 | <select name="type"><option>(Not selected)</option><option>Important</option><option>Not important</option><option>Personal</option></select> |
paulb@141 | 25 | </p> |
paulb@141 | 26 | <p>Itself containing more items:</p> |
paulb@270 | 27 | <p>Sub-item: <input name="subvalue" value="some other value" /><input name="remove2" value="Remove" type="submit" /></p> |
paulb@141 | 28 | </form> |
paulb@615 | 29 | From the item type list only one value may be selected. |
paulb@615 | 30 | <p>Taking the example HTML code from before, we can add a |
paulb@141 | 31 | definition of this new list to the template to produce something |
paulb@141 | 32 | like this:</p> |
paulb@391 | 33 | <pre><html xmlns="http://www.w3.org/1999/xhtml"<br /> xmlns:template="http://www.boddie.org.uk/ns/xmltools/template"><br /><head><br /> <title>Example</title><br /></head><br /><body template:element="structure"><br /><form action="" method="post"><br /><br /><!-- Template text between the start and the interesting part. --><br /><br /><div template:element="item"><br /> <p><br /> Some item: <input template:attribute-field="value" name="..." type="text" value="..." /><br /> <input name="..." template:selector-field="remove" type="submit" value="Remove" /><br /> </p><br /> <span style="font-weight: bold;"><p></span><br style="font-weight: bold;" /><span style="font-weight: bold;"> Item type:</span><br style="font-weight: bold;" /><span style="font-weight: bold;"> <select template:multiple-choice-field="type,value" name="..."></span><br style="font-weight: bold;" /><span style="font-weight: bold;"> <option template:multiple-choice-value="type-enum,value,selected" value="..." /></span><br style="font-weight: bold;" /><span style="font-weight: bold;"> </select></span><br style="font-weight: bold;" /><span style="font-weight: bold;"> </p></span><br /> <p><br /> Itself containing more items:<br /> </p><br /> <p template:element="subitem"><br /> Sub-item: <input template:attribute-field="subvalue" name="..." type="text" value="..." /><br /> <input name="..." template:selector-field="remove2" type="submit" value="Remove" /><br /> </p><br /> <p><br /> <input name="..." template:selector-field="add2,subitem" type="submit" value="Add subitem" /><br /> </p><br /></div><br /><p><br /> <input name="..." template:selector-field="add,item" type="submit" value="Add item" /><br /></p><span style="font-weight: bold;"><br /><br /></span><!-- Template text between the interesting part and the end. --><br /><br /></form><br /></body><br /></html></pre> |
paulb@141 | 34 | <p>There are a lot of details here that need to be explained. Here is |
paulb@141 | 35 | what was done:</p> |
paulb@141 | 36 | <ol> |
paulb@141 | 37 | <li>A paragraph was added to provide some space on the page for the |
paulb@141 | 38 | field.</li> |
paulb@615 | 39 | <li>Inside the paragraph, next to the label text, an HTML <code>select</code> |
paulb@141 | 40 | element was added.</li> |
paulb@615 | 41 | <li>The <code>select</code> element is mapped onto the <code>type</code> |
paulb@615 | 42 | element in the form data structure, indicating using a special <code>template:multiple-choice-field</code> attribute that the <code>value</code> attribute of the <code>type</code> |
paulb@270 | 43 | element will contain any chosen value from the list of values displayed in the page.</li> |
paulb@615 | 44 | <li>Inside the <code>select</code> element, we include an <code>option</code> |
paulb@615 | 45 | element which defines the values which will be presented to users |
paulb@615 | 46 | of the form. Here, the special <code>template:multiple-choice-value</code> attribute indicates that the <code>option</code> element maps onto |
paulb@615 | 47 | a <code>type-enum</code> element which is not mentioned in our |
paulb@141 | 48 | revised form data structure above; this will be discussed below.</li> |
paulb@141 | 49 | </ol> |
paulb@141 | 50 | <h2>Output Structures</h2> |
paulb@141 | 51 | <p>Although we revised the form data structure above, and whilst the |
paulb@141 | 52 | revised structure can describe form data submitted by users of our |
paulb@141 | 53 | application, it is unfortunately not sufficient to define the form data |
paulb@141 | 54 | that is to be presented. Consider the multiple-choice values that shall |
paulb@141 | 55 | be presented to users: such values are not defined in our revised |
paulb@141 | 56 | structure. Therefore, we shall define an output form data structure as |
paulb@141 | 57 | follows:</p> |
paulb@141 | 58 | <pre><?xml version="1.0"?><br /><structure><br /> <item value="some value"><br /> <type value="some type"><br /> <type-enum value="choice #n"/><br /> </type><br /> <subitem subvalue="some other value"/><br /> </item><br /></structure></pre> |
paulb@148 | 59 | <h3>Presenting the Extra Values</h3> |
paulb@615 | 60 | <p>In the template, the <code>option</code> element is presented |
paulb@148 | 61 | using a number of special annotations which make more sense when |
paulb@148 | 62 | considering the above output structure:</p> |
paulb@148 | 63 | <ul> |
paulb@615 | 64 | <li>The <code>template:multiple-choice-value</code> annotation states that the |
paulb@615 | 65 | <code>option</code> element maps into the <code>type-enum</code> |
paulb@615 | 66 | element, meaning that each <code>type-enum</code> element will be |
paulb@148 | 67 | reproduced as an option inside the list or menu presented in the Web |
paulb@148 | 68 | form.</li> |
paulb@615 | 69 | <li>The <code>template:multiple-choice-value</code> annotation also states that the |
paulb@615 | 70 | contents of the <code>option</code> element will correspond to |
paulb@615 | 71 | the value of the <code>type-enum</code> element's <code>value</code> |
paulb@270 | 72 | attribute.</li> |
paulb@615 | 73 | <li>The <code>template:multiple-choice-value</code> annotation provides a final piece of information: the name of an attribute which will be created on the <code>option</code> element if the element's value matches the enclosing <code>select</code> element's value. This has the effect of making sure that the <code>select</code> element always reveals the selected value in its list of values. |
paulb@270 | 74 | </li><li>The <code>value</code> attribute is set to a value which does not matter - it will be replaced in the final output.</li></ul> |
paulb@615 | 75 | <p>The result of this is that the <code>type</code> element in the |
paulb@615 | 76 | this example structure fragment...</p> |
paulb@444 | 77 | <pre><type value="2"><br /> <type-enum value="(Not selected)"/><br /> <type-enum value="Important"/><br /> <type-enum value="Not important"/><br /> <type-enum value="Personal"/><br /></type></pre> |
paulb@148 | 78 | <p>...is transformed into something resembling this HTML code:</p> |
paulb@444 | 79 | <pre><select name="..."><br /> <option value="(Not selected)">(Not selected)</option><br /> <option value="Important" selected="selected">Important</option><br /> <option value="Not important">Not important</option><br /> <option value="Personal">Personal</option><br /></select></pre> |
paulb@148 | 80 | <p>Such presentation techniques are sufficient if the input form data |
paulb@148 | 81 | structure is identical to the output structure, but since we will |
paulb@148 | 82 | receive a structure resembling that defined |
paulb@148 | 83 | earlier (where the multiple-choice values are never sent back to the |
paulb@148 | 84 | application), yet need to present a structure like the one above, we |
paulb@148 | 85 | will |
paulb@141 | 86 | need to find a way of merging the range of allowed values into the |
paulb@141 | 87 | user-edited form data before presenting that data using our template.</p> |
paulb@415 | 88 | <h2><a name="DocumentInitialisation"></a>Document Initialisation</h2> |
paulb@148 | 89 | <p>There are many possible ways of inserting extra XML elements into an |
paulb@270 | 90 | existing XML document, but XSLForms provides an easy way of defining |
paulb@270 | 91 | lists of values that will be included in the way we desire. First, let |
paulb@270 | 92 | us define a |
paulb@148 | 93 | document containing all the possible values for the type field:</p> |
paulb@270 | 94 | <pre><?xml version="1.0"?><br /><type><br /> <type-enum value="(Not selected)"/><br /> <type-enum value="Important"/><br /> <type-enum value="Not important"/><br /> <type-enum value="Personal"/><br /></type></pre> |
paulb@615 | 95 | <p>We shall refer to this document when inserting the different <code>type-enum</code> |
paulb@148 | 96 | elements into our input form data structure to produce the output |
paulb@270 | 97 | structure described above; it can be |
paulb@148 | 98 | found in <code>examples/Common/VerySimple/Resources/structure_types.xml</code>.</p> |
paulb@270 | 99 | <h3>Amending the Resource</h3> |
paulb@270 | 100 | <p>To take advantage of this new information, it is necessary to |
paulb@270 | 101 | 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 |
paulb@270 | 102 | convenient mechanisms for introducing XML documents and initialisations, and we |
paulb@148 | 103 | shall add a few extra attributes to our resource class in order to take |
paulb@148 | 104 | advantage of them:</p> |
paulb@270 | 105 | <pre> # Under template_resources...<br /><br /> init_resources = {<br /> "structure" : ("structure_template.xhtml", "structure_input.xsl")<br /> }<br /> document_resources = {<br /> "types" : "structure_types.xml"<br /> }</pre> |
paulb@148 | 106 | <p>These attributes define the following things:</p> |
paulb@148 | 107 | <ol> |
paulb@270 | 108 | <li>A initialisation called <code>structure</code> which links |
paulb@615 | 109 | the <code>structure_template.xhtml</code> file (the template) to the <code>structure_input.xsl</code> stylesheet file. This is very similar to the way the <code>template_resources</code> dictionary links templates to other stylesheet files producing output.</li> |
paulb@615 | 110 | <li>A document referred to by the name <code>types</code> which |
paulb@615 | 111 | is provided by the <code>structure_types.xml</code> file.</li> |
paulb@148 | 112 | </ol> |
paulb@270 | 113 | <p>To actually perform the initalisation or merge operation, we need to add a few extra |
paulb@615 | 114 | lines of code after the addition and deletion operations in the <code>respond_to_form</code> |
paulb@148 | 115 | method:</p> |
paulb@270 | 116 | <pre> # Under the addition and deletion operations...<br /><br /> # Initialise the document, adding enumerations/ranges.<br /><br /> structure_xsl = self.prepare_initialiser("structure")<br /> types_xml = self.prepare_document("types")<br /> structure = self.get_result([structure_xsl], structure, references={"type" : types_xml})<br /><br /> # Start the response.</pre> |
paulb@148 | 117 | <p>These lines do the following things:</p> |
paulb@148 | 118 | <ol> |
paulb@615 | 119 | <li>Obtain the stylesheet for the <code>structure</code> initialisation.</li> |
paulb@615 | 120 | <li>Obtain the <code>types</code> document containing the |
paulb@148 | 121 | values to be merged into the form data.</li> |
paulb@615 | 122 | <li>Take the stylesheet and apply it to the form data, <code>structure</code>, |
paulb@615 | 123 | using a reference to the <code>types</code> document containing |
paulb@148 | 124 | the values.</li> |
paulb@148 | 125 | </ol> |
paulb@615 | 126 | <p>The result of this should be a processed <code>structure</code> |
paulb@615 | 127 | document containing the type values for each <code>type</code> |
paulb@148 | 128 | element in that document.</p> |
paulb@148 | 129 | <h2>Other Multiple-Choice Data</h2> |
paulb@148 | 130 | <p>We have now added a simple, single-valued multiple-choice field to |
paulb@270 | 131 | the application. However, many applications often need to obtain <a href="multivalue.html">multivalued multiple-choice data</a>, and this |
paulb@148 | 132 | kind of information is investigated in the next part of the development |
paulb@148 | 133 | <a href="overview.html">process</a>.</p> |
paulb@615 | 134 | </body></html> |