# HG changeset patch # User paulb # Date 1122064333 0 # Node ID edcff6139b1904a1059e0fa07551bc07e7fc07a0 # Parent a7ea3c1684c1e479a71631fe955b26a31d02b15c [project @ 2005-07-22 20:32:13 by paulb] Improved and fixed the JavaScript method call description and details. Added a description of the changes required in the Web resource. diff -r a7ea3c1684c1 -r edcff6139b19 docs/in-page-updates.html --- a/docs/in-page-updates.html Fri Jul 22 18:27:00 2005 +0000 +++ b/docs/in-page-updates.html Fri Jul 22 20:32:13 2005 +0000 @@ -128,26 +128,41 @@ added or removed, we add an event attribute on the form field responsible for displaying the type values:
<p>+ style="font-weight: bold;">onchange="requestUpdate(
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:child-attribute('value', template:child-element('comment', 1, template:other-elements(../options)))}',
'/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:
-application-url
which will need to be provided to the template when generating the Web
-page.http://localhost:8080/comments+So the request for an in-page update will be sent to this +generated URL. +
type
element and its type-enum
elements' value
attributes, we specify the names of
-the fields which yield these values.options
element holding comment
element. Thus, we use a
special value which also refers to that element from the context of
-the type
element.type
element.
+ template:child-attribute
-and template:child-element
functions.template:child-element
functions.
+ Of course, all this is pretty complicated and at some point in the +future, a simplified way of triggering in-page updates will be +introduced.
+To support both normal requests for Web pages and the special +in-page requests, we must make some modifications to the Web +application. First, we must introduce some infrastructure to handle the +requests for the JavaScript files separately from the requests for +pages from our application. Some standard WebStack resources can be +used to help with this, and we add some imports at the top of our +source file:
+#!/usr/bin/env python+
"A very simple example application."
import WebStack.Generic
import XSLForms.Resources
import XSLForms.Utils
import os
# Site map imports.
from WebStack.Resources.ResourceMap import MapResource
from WebStack.Resources.Static import DirectoryResource
Then, we define the resource class as before, +but with an additional attribute:
+# Resource classes.+
class VerySimpleResource(XSLForms.Resources.XSLFormsResource):
"A very simple resource providing a hierarchy of editable fields."
resource_dir = os.path.join(os.path.split(__file__)[0], "Resources")
encoding = "utf-8"
template_resources = {
"structure" : ("structure_multivalue_template.xhtml", "structure_output.xsl")
}
transform_resources = {
"types" : ["structure_multivalue_types.xsl", "structure_comments.xsl"]
}
document_resources = {
"types" : "structure_types.xml"
}
in_page_resources = {
"comments" : ("structure_output_comments.xsl", "comment-node")
}
This new attribute provides information about the in-page request to +retrieve comment regions of the Web form, and it consists of the +stylesheet filename that will be generated to produce the page +fragments for such comment regions, along with the region marker that +we defined above.
+The respond_to_form
method now also includes some
+additional code:
def respond_to_form(self, trans, form):+
"""
Respond to a request having the given transaction 'trans' and the given
'form' information.
"""
in_page_resource = self.get_in_page_resource(trans)
parameters = form.get_parameters()
documents = form.get_documents()
Here, we find out whether an in-page update is requested, along with +the raw parameters of the request, some of which will be used later on +in the method.
+The discovery of the form data structure and the addition and +removal of elements happens as before, as does the merging of type +values and the comment field, if applicable:
+# Ensure the presence of a document.+
if documents.has_key("structure"):
structure = documents["structure"]
else:
structure = form.new_instance("structure")
# Add and remove elements according to the selectors found.
selectors = form.get_selectors()
XSLForms.Utils.remove_elements(selectors.get("remove2"))
XSLForms.Utils.add_elements(selectors.get("add2"), "subitem")
XSLForms.Utils.remove_elements(selectors.get("remove"))
XSLForms.Utils.add_elements(selectors.get("add"), "item")
# Transform, adding enumerations/ranges.
types_xsl_list = self.prepare_transform("types")
types_xml = self.prepare_document("types")
structure = self.get_result(types_xsl_list, structure, references={"types" : types_xml})
The significant changes begin when presenting the result of the +request processing:
+# Start the response.+
trans.set_content_type(WebStack.Generic.ContentType("application/xhtml+xml", self.encoding))
# Define the stylesheet parameters.
stylesheet_parameters = {}
# Ensure that an output stylesheet exists.
if in_page_resource in self.in_page_resources.keys():
trans_xsl = self.prepare_fragment("structure", in_page_resource)
element_path = parameters.get("element-path", [""])[0]
stylesheet_parameters["element-path"] = element_path
else:
trans_xsl = self.prepare_output("structure")
Instead of just obtaining a stylesheet for the structure
+document, we instead check to see if an in-page update is being
+requested and, if so, prepare the stylesheet representing the fragment
+of the Web form to be presented. Additionally, we obtain a special element-path
+parameter directly from the request parameters; this parameter is added
+to a collection of parameters that will be used to control the
+stylesheet when making the final Web page output.
Another parameter that will be used in stylesheet processing is
+the application-url
parameter mentioned above. We
+obtain the address and port of the Web server environment and add the
+result as a simple URL to the application-url
+stylesheet parameter. Finally, we send the output to the user but
+employing the additional stylesheet parameters to configure the result:
# Add information essential for in-page requests.+
if trans.get_server_port() == "80":
stylesheet_parameters["application-url"] = \
"http://%s%s" % (trans.get_server_name(), trans.get_path_without_query())
else:
stylesheet_parameters["application-url"] = \
"http://%s:%s%s" % (trans.get_server_name(), trans.get_server_port(), trans.get_path_without_query())
# Complete the response.
self.send_output(trans, [trans_xsl], structure, stylesheet_parameters)
In order to introduce the infrastructure mentioned above which
+separates requests for Web pages from requests for JavaScript files, we
+need to provide a more sophisticated implementation of the get_site
+function:
# Site map initialisation.+
def get_site():
"Return a simple Web site resource."
# Get the main resource and the directory used by the application.
very_simple_resource = VerySimpleResource()
directory = very_simple_resource.resource_dir
# Make a simple Web site.
resource = MapResource({
# Static resources:
"scripts" : DirectoryResource(os.path.join(directory, "scripts"), {"js" : "text/javascript"}),
# Main page and in-page resources:
None : very_simple_resource
})
return resource
What this does is to create a resource for the application, as +before, but then to place the resource into a special WebStack resource +which examines the path or URL on the incoming requests and directs +such requests according to the following scheme:
+scripts
+in its URL, we employ the WebStack DirectoryResource
to
+send the file from the scripts
subdirectory of the
+application's Resources
directory.Thus, when the user's browser asks for a script file, it gets a +script file; otherwise it gets a Web page showing either all of the +form (if a normal request is received), or a part of the form (if an +in-page request is received).