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 Multivalued Fields</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 Multivalued Fields</h1> 12 <p>Although some applications only require multiple-choice fields where 13 only a single value may be chosen, in many situations it is desirable 14 to be able to choose an arbitrary number of values for a particular 15 field. However, up to this point, we have been content to 16 represent form data using a single attribute on a single element to 17 represent any given field value. With multivalued fields, we must 18 choose a different strategy in using XML to represent such information.</p> 19 <p>Let us consider permitting multiple type values to be associated 20 with our items. We revise our <a href="data.html">form data structure</a> 21 to 22 be the following:</p> 23 <pre><?xml version="1.0"?><br /><structure><br /> <item value="some value"><br /> <types><br /> <type value="some type"/><br /> <type value="some other type"/><br /> </types><br /> <subitem subvalue="some other value"/><br /> </item><br /></structure></pre> 24 <h2>Multivalued Fields</h2> 25 <p>We shall now take advantage of those HTML form fields which permit 26 users to select one 27 or many values presented in a list or menu.</p> 28 <form method="post" action="" name="single"> 29 <p>Some item: <input name="value" value="some value" /><input 30 name="remove" value="Remove" type="submit" /></p> 31 <p>Item type: 32 <select multiple="multiple" name="type"> 33 <option>(Not selected)</option> 34 <option>Important</option> 35 <option>Not important</option> 36 <option>Personal</option> 37 </select> 38 </p> 39 <p>Itself containing more items:</p> 40 <p>Sub-item: <input name="subvalue" value="some other value" /><input 41 name="remove2" value="Remove" type="submit" /></p> 42 </form> 43 From the item type list many value may now be selected. 44 <p>Taking the example HTML code from before, we can add a 45 definition of this new list to the template to produce something 46 like this:</p> 47 <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="value" name="{template:this-attribute()}" type="text" value="{$this-value}" /><br /> <input name="remove={template:this-element()}" type="submit" value="Remove" /><br /> </p><br /> <span 48 style="font-weight: bold;"><p template:element="types"></span><br /> Item type:<br /> <select template:element="type" name="<span 49 style="font-weight: bold;">{template:list-attribute('value')}</span>" <span 50 style="font-weight: bold;">multiple="multiple"</span>><br /> <option template:element="type-enum" template:expr="<span 51 style="font-weight: bold;">@value-is-set</span>" template:expr-attr="selected"<br /> template:value="@value" value="{@value}" /><br /> </select><br /> </p><br /> <p><br /> Itself containing more items:<br /> </p><br /> <p template:element="subitem"><br /> Sub-item: <input template:attribute="subvalue" name="{template:this-attribute()}" type="text" value="{$this-value}" /><br /> <input name="remove2={template:this-element()}" type="submit" value="Remove" /><br /> </p><br /> <p><br /> <input name="add2={template:this-element()}" type="submit" value="Add subitem" /><br /> </p><br /></div><br /><p><br /> <input name="add={template:this-element()}" type="submit" value="Add item" /><br /></p><span 52 style="font-weight: bold;"><br /><br /></span><!-- Template text between the interesting part and the end. --><br /><br /></form><br /></body><br /></html></pre> 53 <p>From the previous <a href="mulitple.html">single-valued case</a>, 54 some crucial changes have been made:</p> 55 <ol> 56 <li>The paragraph surrounding the field has been annotated to map 57 onto the <code>types</code> element in the form data structure.</li> 58 <li>The <code>select</code> element remains mapped onto the <code>type</code> 59 element in the form data structure. However, we indicate in the name of 60 the <code>select</code> 61 element that the value submitted maps onto a special kind of attribute. 62 Instead of mapping onto a single attribute on a single element, the 63 value maps onto a single attribute on a single element <span 64 style="font-style: italic;">for each value submitted</span>. So for 65 each value selected in the list or menu, a <code>type</code> 66 element is created with the <code>value</code> 67 attribute containing that value.</li> 68 <li>Of course, the <code>select</code> element now has a <code>multiple</code> 69 attribute defined to permit multiple value selections.</li> 70 <li>Inside the <code>select</code> element, the <code>option</code> 71 element mapping onto 72 a <code>type-enum</code> element using a different <code>template:expr</code> 73 condition than was used before.</li> 74 </ol> 75 <h2>Output Structures</h2> 76 <p>Just as in the single-valued case, the revised the form data 77 structure for input does not quite match the structure used by the 78 template. Therefore, we shall define an output form data structure as 79 follows:</p> 80 <pre><?xml version="1.0"?><br /><structure><br /> <item value="some value"><br /> <types><br /> <type><br /> <type-enum value="some type"/><br /> <type-enum value="some other type"/><br /> </type><br /> </types><br /> <subitem subvalue="some other value"/><br /> </item><br /></structure></pre> 81 <p>It is worth noting that the above structure does not define whether 82 many <code>type</code> elements will exist within each <code>types</code> 83 element or whether another mechanism will be used to specify multiple 84 values for each type field.<br /> 85 </p> 86 <h3>Presenting the Extra Values</h3> 87 <p>In most respects, the presentation of the extra values is the same 88 as in the single-valued case. The result of the presentation of the 89 extra values is that the <code>types</code> element in the 90 this example structure fragment...</p> 91 <pre><types><br /> <type><br /> <type-enum value="1"/><br /> <type-enum value="2" value-is-set="true"/><br /> <type-enum value="3" value-is-set="true"/><br /> </type><br /></types></pre> 92 <p>...is transformed into something resembling this HTML code:</p> 93 <pre><p><br /> <select name="..." multiple="multiple"><br /> <option value="1">1</option><br /> <option value="2" selected="selected">2</option><br /> <option value="3" selected="selected">3</option><br /> </select><br /></p></pre> 94 <p>Numerous issues arise when considering the above transformation:</p> 95 <ul> 96 <li>Were we not supposed to have many <code>type</code> elements?</li> 97 <li>Where does the special <code>value-is-set</code> attribute 98 come from?</li> 99 </ul> 100 Here, we have made a strategic decision: with the template as defined 101 above, many <code>type</code> elements would have produced 102 many <code>select</code> elements in the Web form, yet this is not 103 what we want; we need to restrict the number of <code>select</code> 104 elements to one per <code>types</code> element whilst marking the 105 selected values so that they may be displayed appropriately in the list 106 or menu. 107 <h2>Merging and Collecting Values</h2> 108 <p>As in the single-valued case, we need to insert the permitted values 109 into the form data so that the template may visit the <code>type-enum</code> 110 elements and extract those values. However, we have now introduced 111 another task to this activity: to collect the selected values together 112 and to produce a unified <code>type</code> element within 113 each <code>types</code> element. In other words, we want to turn 114 something like this...</p> 115 <pre><types><br /> <type value="2"/><br /> <type value="3"/><br /></types></pre> 116 <p>...into something like this:</p> 117 <pre><types><br /> <type><br /> <type-enum value="1"/><br /> <type-enum value="2" value-is-set="true"/><br /> <type-enum value="3" value-is-set="true"/><br /> </type><br /></types></pre> 118 Using the same document containing all the permitted values as our 119 source of information to be merged into the form data, we can now 120 develop a stylesheet which performs the above transformation; this 121 stylesheet needs to work on the 122 following principles: 123 <ol> 124 <li>Descend into the form data structure, copying all elements, 125 attributes and text that the stylesheet is not programmed to recognise.</li> 126 <li>When encountering an <code>item</code> element (which the 127 stylesheet is programmed to recognise), do the following:<br /> 128 <ol> 129 <li>Copy the element "skeleton" and its attributes so that 130 the <code>value</code> attribute is retained.</li> 131 <li>Produce a new <code>types</code> element and process it.</li> 132 </ol> 133 </li> 134 <li>When processing a new <code>types</code> element, do the 135 following:<br /> 136 <ol> 137 <li>Add a single <code>type</code> element within it.</li> 138 <li>Inside this new <code>type</code> element, add the <code>type-enum</code> 139 elements from the 140 document containing the values, and if any <code>type</code> 141 elements were found within the <code>item</code> element, specify 142 these for the activity.</li> 143 </ol> 144 </li> 145 <li>When adding the <code>type-enum</code> elements, if any of 146 them have a <code>value</code> attribute which matches any of the <code>value</code> 147 attributes of the found <code>type</code> elements, set the special 148 <code>value-is-set</code> attribute on that <code>type-enum</code> 149 element.</li> 150 </ol> 151 <p>The stylesheet source code can be found in <code>examples/Common/VerySimple/Resources/structure_multivalue_types.xsl</code>, 152 whereas the document defined above which contains the values can be 153 found in <code>examples/Common/VerySimple/Resources/structure_types.xml</code>.</p> 154 <h3>Updating the Web Resource</h3> 155 <p>To update the special WebStack resource, we 156 now need to modify a few of the class attributes and to add a few 157 others:</p> 158 <pre> template_resources = {<br /> "structure" : ("structure_multivalue_template.xhtml", "structure_output.xsl")<br /> }<br /> transform_resources = {<br /> "types" : ["structure_multivalue_types.xsl"]<br /> }<br /></pre> 159 <p>With these adjustments, it should now be possible to manipulate the 160 items and subitems whilst specifying multiple type values on each item.</p> 161 </body> 162 </html>