# HG changeset patch # User paulb # Date 1121990089 0 # Node ID b56954a07123977a87c43657af7f92697dcb02d9 # Parent 07283b4de61407d8ebb83df6aeed21320bd31b3e [project @ 2005-07-21 23:54:49 by paulb] Added the start of in-page update documentation. diff -r 07283b4de614 -r b56954a07123 docs/in-page-updates.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/in-page-updates.html Thu Jul 21 23:54:49 2005 +0000 @@ -0,0 +1,163 @@ + + + + + Creating Applications: In-Page Updates + + + + +

Creating Applications: In-Page Updates

+

One fashionable avenue in Web application design has been that of +updating Web pages in applications without having to refresh the entire +page every time an action is performed. Together with some JavaScript +support in the browser, XSLForms also provides some functionality for +such "in-page" or "live" updates.

+

Consider the addition of a comment field to our application. Here is +how the HTML code might look:

+
<div template:element="item">
<p>
Some item: <input template:attribute="value" name="{template:this-attribute()}" type="text" value="{$this-value}" />
<input name="remove={template:this-element()}" type="submit" value="Remove" />
</p>
<p>
Item type:
<select template:element="type" name="{template:list-attribute('type-enum', 'value')}" multiple="multiple">
<option template:element="type-enum" template:expr="@value-is-set" template:expr-attr="selected"
template:value="@value" value="{@value}" />
</select>
</p>
<p template:element="options">
<span template:element="comment">Comment:
<textarea template:attribute="value" name="{template:this-attribute()}" cols="40" rows="3">
<span template:value="$this-value" template:effect="replace">Some comment</span>
</textarea>
</span>
</p>
<p>
Itself containing more items:
</p>
<p template:element="subitem">
Sub-item: <input template:attribute="subvalue" name="{template:this-attribute()}" type="text" value="{$this-value}" />
<input name="remove2={template:this-element()}" type="submit" value="Remove" />
</p>
<p>
<input name="add2={template:this-element()}" type="submit" value="Add subitem" />
</p>
</div>
+

The newly-added textarea field will not be +presented in the application in its current state; this is due to the +lack of any options or comment elements +manipulated by the +application, and such template changes are actually quite safe to make. +So, we must now do some additional work to add such options +and comment +elements in our application.

+

One approach is to extend our transformation which adds the +different type values so that these new elements are +introduced as well. In the Web resource, we can make the following +change:

+
    transform_resources = {
"types" : ["structure_multivalue_types.xsl", "structure_comments.xsl"]
}
+

What this does is to state that when we carry out the types +transformation, two stylesheets are employed, one before the other, +such that the type values are first added using the first stylesheet +(and the additional reference document containing the type values) and +that the comments are then added using the second stylesheet.

+

This new stylesheet works according to the following principles:

+
    +
  1. Descend into the form data structure, copying all elements, +attributes and text that the stylesheet is not programmed to recognise.
  2. +
  3. When encountering an item element (which the +stylesheet is programmed to recognise), do the following:
    +
      +
    1. Copy the element "skeleton" and its attributes so that +the value attribute is retained.
    2. +
    3. Produce a new options element and process it.
    4. +
    +
  4. +
  5. When processing a new options element, do the +following:
    +
      +
    1. Inside this new options element, investigate +the values associated with the type element.
    2. +
    3. If any of the selected type values is "Personal", make a new comment +element, then add any attributes that may be found on existing + comment elements within the current type +element.
    4. +
    +
  6. +
+

Since this stylesheet is used after the type value transformation, +we may (and even must) take advantage of the results of that +transformation, including noting that selected values on type-enum +elements are marked with the value-is-set attribute.

+

The stylesheet source code can be found in examples/Common/VerySimple/Resources/structure_comments.xsl.

+

Limitations and Enhancements

+

Whilst the above modifications adds a comment field for each item +with a type of "Personal", and whilst the comment field will appear and +disappear for items as their type changes, such updates only take place +when items and subitems are added and removed. We could add an update +button to the page which performs an explicit refresh of the page +without adding or removing anything, and for the sake of usability, we +probably should add such a button (just below the Add item +button):

+
<p>
<input name="update" type="submit" value="Update" />
</p>
+

However, we could also add an in-page update to make each comments +field appear and disappear as soon as we have changed the type of an +item.

+

Template Changes

+

We must first define a region of the template where a comment fields +can be added and removed, regardless of whether such a field existed +there before. The above template code needs modifying slightly to +permit this:

+
  <p template:element="options" template:id="comment-node" id="{template:this-element()}">
<span template:element="comment">Comment:
<textarea template:attribute="value" name="{template:this-attribute()}" cols="40" rows="3">
<span template:value="$this-value" template:effect="replace">Some comment</span>
</textarea>
</span>
</p>
+

Here, we have added this region definition to the paragraph +surrounding the comment field, annotating the paragraph with the +following attributes:

+ +

Another change has been to put the template:element +annotation inside the above fragment or region annotations. Had we not +done this, the lack of a comment element in the form +data could have prevented the id attribute from +appearing in the Web page, this preventing any hope of an in-page +update since there would be no way of knowing where such an update +should be applied.

+

Adding JavaScript

+

Since we rely on JavaScript support in the browser, the following +references to scripts must also be added to the template, as shown in +the following excerpt:

+
<head>
<title>Example</title>
<script type="text/javascript" src="scripts/sarissa.js"> </script>
<script type="text/javascript" src="scripts/XSLForms.js"> </script>
</head>
+

These special script files can be found in examples/Common/VerySimple/Resources/scripts.

+

Now we can concentrate on adding the event which triggers an in-page +update. Since it is the type values that cause each comment field to be +added or removed, we add an event attribute on the form field +responsible for displaying the type values:

+
  <p>
Item type:
<select template:element="type" name="{template:list-attribute('type-enum', 'value')}" multiple="multiple"
onchange="requestUpdate('{$application-url}comments', '{template:list-attribute('type-enum', 'value')}',
 '{template:other-elements(../options)}', '{template:other-attributes('value', ../options/comment)}',
'/structure/item/options')"
>
<option template:element="type-enum" template:expr="@value-is-set" template:expr-attr="selected"
template:value="@value" value="{@value}" />
</select>
</p>
+

This complicated string calls a special update request JavaScript +function which triggers the in-page update, and it specifies the +following things:

+
    +
  1. The URL which will serve the in-page update requested by this +field. We use a special variable called application-url +which will need to be provided to the template when generating the Web +page.
  2. +
  3. The fields which are going to be used in the processing of the +update. Since the presence of the comment field depends on a +specific type element and its type-enum +elements' value attributes, we specify the names of +the fields which yield these values.
  4. +
  5. The region which is to be updated. Here, we recall that we +defined the region using a special reference to the options +element holding comment element. Thus, we use a +special value which also refers to that element from the context of +the type element.
  6. +
  7. Even when the types are changed, it may be the case that an +exposed comment field does not disappear (for example, if we already +have "Personal" selected but select "Important" in addition), and so we +need to provide the details of the field which holds the value of the +comment text. We find such details by referencing the comment +element from the type element and stating that we want the + value attribute on that comment +element.
  8. +
  9. Finally, we need to provide some context to the application to +tell it something about where in the complete form data structure the +updated information resides. 
  10. +
+ +