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 /> <type><br /> <type-enum value="some type"/><br /> <type-enum value="some other type"/><br /> </type><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></span><br /> Item type:<br /> <select template:element="type" name="<span 49 style="font-weight: bold;">{template:list-attribute('type-enum', '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="multiple.html">single-valued case</a>, 54 some crucial changes have been made:</p> 55 <ol> 56 <li>The <code>select</code> element remains mapped onto the <code>type</code> 57 element in the form data structure. However, we indicate in the name of 58 the <code>select</code> 59 element that the value submitted maps onto a special kind of attribute. 60 Instead of mapping onto a single attribute on a single element, the 61 value maps onto a single attribute on a single element <span 62 style="font-style: italic;">for each value submitted</span>. So for 63 each value selected in the list or menu, a <code>type-enum</code> 64 element is created (inside the <code>type</code> element) with a <code>value</code> 65 attribute containing that value.</li> 66 <li>Of course, the <code>select</code> element now has a <code>multiple</code> 67 attribute defined to permit multiple value selections.</li> 68 <li>Inside the <code>select</code> element, the <code>option</code> 69 element mapping onto 70 a <code>type-enum</code> element using a different <code>template:expr</code> 71 condition than was used before.</li> 72 </ol> 73 <h2>Output Structures</h2> 74 <p>Unlike in the single-valued case, the revised the form data 75 structure for input is almost the same as the structure used by the 76 template. Indeed, the subtle differences cannot be represented in our 77 simplistic presentation of the structure:</p> 78 <pre><?xml version="1.0"?><br /><structure><br /> <item value="some value"><br /> <type><br /> <type-enum value="some type"/><br /> <type-enum value="some other type"/><br /> </type><br /> <subitem subvalue="some other value"/><br /> </item><br /></structure></pre> 79 <p>In fact, the principal difference arises through the number of <code>type-enum</code> 80 elements that occur in the input, representing the values selected by 81 the user, and the number that occur in the output, representing the 82 complete range of values available for selection. 83 </p> 84 <h3>Presenting the Extra Values</h3> 85 <p>In most respects, the presentation of the extra values is the same 86 as in the single-valued case. The result of the presentation of the 87 extra values is that the <code>type</code> element in the 88 this example structure fragment...</p> 89 <pre><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 /></pre> 90 <p>...is transformed into something resembling this HTML code:</p> 91 <pre><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 /></pre> 92 <p>One principal issue arises when considering the above 93 transformation: where does the special <code>value-is-set</code> 94 attribute 95 come from?</p> 96 <ul> 97 </ul> 98 Here, we have to do two things: to include the full range of possible 99 values so that the user may select from that range, and yet we must 100 remember which values were previously selected. If we just merged 101 the <code>type-enum</code> elements into the <code>type</code> 102 element, we would lose track of which values were selected. Therefore, 103 we need to employ a different strategy in remembering those values than 104 that of assuming that those <code>type-enum</code> elements which 105 are present are those which are selected. 106 <h2>Merging and Collecting Values</h2> 107 <p>As in the single-valued case, we need to insert the permitted values 108 into the form data so that the template may visit the <code>type-enum</code> 109 elements and extract those values. However, we have now introduced 110 another task to this activity: to mark the selected values in the 111 entire list of <code>type-enum</code> elements in order to 112 distinguish them from the values which are not selected. In other 113 words, we want to turn 114 something like this...</p> 115 <pre><type><br /> <type-enum value="2"/><br /> <type-enum value="3"/><br /></type><br /></pre> 116 <p>...into something like this:</p> 117 <pre><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 /></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>type</code> element and process it.</li> 132 </ol> 133 </li> 134 <li>When processing a new <code>type</code> element, do the 135 following:<br /> 136 <ol> 137 <li>Inside this new <code>type</code> element, add the <code>type-enum</code> 138 elements from the 139 values document, and if any <code>type-enum</code> 140 elements were found within an existing <code>type</code> element from 141 the form data, 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-enum</code> elements, set the 148 special <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. 161 Note that it may be necessary to remove the old stylesheet for 162 producing output, <code>structure_output.xsl</code>, so that the 163 multivalue version of the template is taken into use.</p> 164 <h2>Further Reading</h2> 165 <p>Now that we have designed and implemented a simple application, it 166 may be worth reading some <a href="advice.html">recommendations</a> 167 about developing your own applications.</p> 168 </body> 169 </html>