1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docs/in-page-updates.html Thu Jul 21 23:54:49 2005 +0000
1.3 @@ -0,0 +1,163 @@
1.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1.5 +<html xmlns="http://www.w3.org/1999/xhtml">
1.6 +<head>
1.7 + <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" />
1.8 + <title>Creating Applications: In-Page Updates</title>
1.9 + <meta name="generator"
1.10 + content="amaya 8.1a, see http://www.w3.org/Amaya/" />
1.11 + <link href="styles.css" rel="stylesheet" type="text/css" />
1.12 +</head>
1.13 +<body>
1.14 +<h1>Creating Applications: In-Page Updates</h1>
1.15 +<p>One fashionable avenue in Web application design has been that of
1.16 +updating Web pages in applications without having to refresh the entire
1.17 +page every time an action is performed. Together with some JavaScript
1.18 +support in the browser, XSLForms also provides some functionality for
1.19 +such "in-page" or "live" updates.</p>
1.20 +<p>Consider the addition of a comment field to our application. Here is
1.21 +how the HTML code might look:</p>
1.22 +<pre><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 /> <p><br /> Item type:<br /> <select template:element="type" name="{template:list-attribute('type-enum', 'value')}" multiple="multiple"><br /> <option template:element="type-enum" template:expr="@value-is-set" template:expr-attr="selected"<br /> template:value="@value" value="{@value}" /><br /> </select><br /> </p><br /> <span
1.23 + style="font-weight: bold;"><p template:element="options"></span><br
1.24 + style="font-weight: bold;" /><span style="font-weight: bold;"> <span </span><span
1.25 + style="font-weight: bold;">template:element="comment"></span><span
1.26 + style="font-weight: bold;">Comment:</span><br
1.27 + style="font-weight: bold;" /><span style="font-weight: bold;"> <textarea template:attribute="value" name="{template:this-attribute()}" cols="40" rows="3"></span><br
1.28 + style="font-weight: bold;" /><span style="font-weight: bold;"> <span template:value="$this-value" template:effect="replace">Some comment</span></span><br
1.29 + style="font-weight: bold;" /><span style="font-weight: bold;"> </textarea><br /> </span><br
1.30 + style="font-weight: bold;" /></span><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="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></pre>
1.31 +<p>The newly-added <code>textarea</code> field will not be
1.32 +presented in the application in its current state; this is due to the
1.33 +lack of any <code>options</code> or <code>comment</code> elements
1.34 +manipulated by the
1.35 +application, and such template changes are actually quite safe to make.
1.36 +So, we must now do some additional work to add such <code>options</code>
1.37 +and <code>comment</code>
1.38 +elements in our application.</p>
1.39 +<p>One approach is to extend our transformation which adds the
1.40 +different type values so that these new elements are
1.41 +introduced as well. In the Web resource, we can make the following
1.42 +change:</p>
1.43 +<pre> transform_resources = {<br /> "types" : ["structure_multivalue_types.xsl", "structure_comments.xsl"]<br /> }</pre>
1.44 +<p>What this does is to state that when we carry out the <code>types</code>
1.45 +transformation, two stylesheets are employed, one before the other,
1.46 +such that the type values are first added using the first stylesheet
1.47 +(and the additional reference document containing the type values) and
1.48 +that the comments are then added using the second stylesheet.</p>
1.49 +<p>This new stylesheet works according to the following principles:</p>
1.50 +<ol>
1.51 + <li>Descend into the form data structure, copying all elements,
1.52 +attributes and text that the stylesheet is not programmed to recognise.</li>
1.53 + <li>When encountering an <code>item</code> element (which the
1.54 +stylesheet is programmed to recognise), do the following:<br />
1.55 + <ol>
1.56 + <li>Copy the element "skeleton" and its attributes so that
1.57 +the <code>value</code> attribute is retained.</li>
1.58 + <li>Produce a new <code>options</code> element and process it.</li>
1.59 + </ol>
1.60 + </li>
1.61 + <li>When processing a new <code>options</code> element, do the
1.62 +following:<br />
1.63 + <ol>
1.64 + <li>Inside this new <code>options</code> element, investigate
1.65 +the values associated with the <code>type</code> element.</li>
1.66 + <li>If any of the selected type values is "Personal", make a new <code>comment</code>
1.67 +element, then add any attributes that may be found on existing
1.68 + <code>comment</code> elements within the current <code>type</code>
1.69 +element.</li>
1.70 + </ol>
1.71 + </li>
1.72 +</ol>
1.73 +<p>Since this stylesheet is used after the type value transformation,
1.74 +we may (and even must) take advantage of the results of that
1.75 +transformation, including noting that selected values on <code>type-enum</code>
1.76 +elements are marked with the <code>value-is-set</code> attribute.</p>
1.77 +<p>The stylesheet source code can be found in <code>examples/Common/VerySimple/Resources/structure_comments.xsl</code>.</p>
1.78 +<h2>Limitations and Enhancements</h2>
1.79 +<p>Whilst the above modifications adds a comment field for each item
1.80 +with a type of "Personal", and whilst the comment field will appear and
1.81 +disappear for items as their type changes, such updates only take place
1.82 +when items and subitems are added and removed. We could add an update
1.83 +button to the page which performs an explicit refresh of the page
1.84 +without adding or removing anything, and for the sake of usability, we
1.85 +probably should add such a button (just below the <code>Add item</code>
1.86 +button):</p>
1.87 +<pre><p><br /> <input name="update" type="submit" value="Update" /><br /></p></pre>
1.88 +<p>However, we could also add an in-page update to make each comments
1.89 +field appear and disappear as soon as we have changed the type of an
1.90 +item.</p>
1.91 +<h3>Template Changes</h3>
1.92 +<p>We must first define a region of the template where a comment fields
1.93 +can be added and removed, regardless of whether such a field existed
1.94 +there before. The above template code needs modifying slightly to
1.95 +permit this:</p>
1.96 +<pre> <span style="font-weight: bold;"><p template:element="options" template:id="comment-node" id="{template:this-element()}"></span><br
1.97 + style="font-weight: bold;" /><span style="font-weight: bold;"> <span template:element="comment"></span>Comment:<br /> <textarea template:attribute="value" name="{template:this-attribute()}" cols="40" rows="3"><br /> <span template:value="$this-value" template:effect="replace">Some comment</span><br /> </textarea><br /> <span
1.98 + style="font-weight: bold;"></span></span><br /> </p></pre>
1.99 +<p>Here, we have added this region definition to the paragraph
1.100 +surrounding the comment field, annotating the paragraph with the
1.101 +following attributes:</p>
1.102 +<ul>
1.103 + <li>The <code>template:id</code> attribute is used to define a
1.104 +template fragment used only to prepare the updated part of the Web
1.105 +page. Here we define the fragment or region as being just this
1.106 +paragraph.</li>
1.107 + <li>The standard HTML <code>id</code> attribute is used to
1.108 +define which part of the active Web page will be replaced when
1.109 +performing an in-page update. This attribute needs to have a unique
1.110 +value, but the easiest basis for such a value is a selector-style
1.111 +reference to the <code>options</code> element within which the <code>comment</code>
1.112 +element resides.</li>
1.113 +</ul>
1.114 +<p>Another change has been to put the <code>template:element</code>
1.115 +annotation inside the above fragment or region annotations. Had we not
1.116 +done this, the lack of a <code>comment</code> element in the form
1.117 +data could have prevented the <code>id</code> attribute from
1.118 +appearing in the Web page, this preventing any hope of an in-page
1.119 +update since there would be no way of knowing where such an update
1.120 +should be applied.</p>
1.121 +<h3>Adding JavaScript</h3>
1.122 +<p>Since we rely on JavaScript support in the browser, the following
1.123 +references to scripts must also be added to the template, as shown in
1.124 +the following excerpt:</p>
1.125 +<pre><head><br /> <title>Example</title><br /> <span
1.126 + style="font-weight: bold;"><script type="text/javascript" src="scripts/sarissa.js"> </script></span><br
1.127 + style="font-weight: bold;" /><span style="font-weight: bold;"> <script type="text/javascript" src="scripts/XSLForms.js"> </script></span><br /></head></pre>
1.128 +<p>These special script files can be found in <code>examples/Common/VerySimple/Resources/scripts</code>.</p>
1.129 +<p>Now we can concentrate on adding the event which triggers an in-page
1.130 +update. Since it is the type values that cause each comment field to be
1.131 +added or removed, we add an event attribute on the form field
1.132 +responsible for displaying the type values:</p>
1.133 +<pre> <p><br /> Item type:<br /> <select template:element="type" name="{template:list-attribute('type-enum', 'value')}" multiple="multiple"<br /> <span
1.134 + style="font-weight: bold;">onchange="requestUpdate('{$application-url}comments', '{template:list-attribute('type-enum', 'value')}',<br /> '{template:other-elements(../options)}', '{template:other-attributes('value', ../options/comment)}',<br /> '/structure/item/options')"</span>><br /> <option template:element="type-enum" template:expr="@value-is-set" template:expr-attr="selected"<br /> template:value="@value" value="{@value}" /><br /> </select><br /> </p></pre>
1.135 +<p>This complicated string calls a special update request JavaScript
1.136 +function which triggers the in-page update, and it specifies the
1.137 +following things:</p>
1.138 +<ol>
1.139 + <li>The URL which will serve the in-page update requested by this
1.140 +field. We use a special variable called <code>application-url</code>
1.141 +which will need to be provided to the template when generating the Web
1.142 +page.</li>
1.143 + <li>The fields which are going to be used in the processing of the
1.144 +update. Since the presence of the comment field depends on a
1.145 +specific <code>type</code> element and its <code>type-enum</code>
1.146 +elements' <code>value</code> attributes, we specify the names of
1.147 +the fields which yield these values.</li>
1.148 + <li>The region which is to be updated. Here, we recall that we
1.149 +defined the region using a special reference to the <code>options</code>
1.150 +element holding <code>comment</code> element. Thus, we use a
1.151 +special value which also refers to that element from the context of
1.152 +the <code>type</code> element.</li>
1.153 + <li>Even when the types are changed, it may be the case that an
1.154 +exposed comment field does not disappear (for example, if we already
1.155 +have "Personal" selected but select "Important" in addition), and so we
1.156 +need to provide the details of the field which holds the value of the
1.157 +comment text. We find such details by referencing the <code>comment</code>
1.158 +element from the <code>type</code> element and stating that we want the
1.159 + <code>value</code> attribute on that <code>comment</code>
1.160 +element.</li>
1.161 + <li>Finally, we need to provide some context to the application to
1.162 +tell it something about where in the complete form data structure the
1.163 +updated information resides. </li>
1.164 +</ol>
1.165 +</body>
1.166 +</html>