A document has been updated:
http://cocoon.zones.apache.org/daisy/documentation/750.html
Document ID: 750
Branch: main
Language: default
Name: Ajax (unchanged)
Document Type: Cocoon Document (unchanged)
Updated on: 10/23/05 8:58:06 PM
Updated by: Sylvain Wallez
A new version has been created, state: publish
Parts
=====
Content
-------
This part has been updated.
Mime type: text/xml (unchanged)
File name: (unchanged)
Size: 8090 bytes (previous version: 597 bytes)
Content diff:
<html>
<body>
--- <p>Starting with Cocoon 2.1.8, CForms offers (mostly) transparent Ajax
support.
--- Ajax is the catchy name for using Javascript and assynchronous web server
--- communication to offer a better user experience in the browser. Within
CForms,
--- this allows for example to update only the parts of the page that require
--- updating, without refreshing the entire page. Enabling Ajax for existing
CForms
--- is straightforward.</p>
+++ <h1>Introduction</h1>
--- <p>For more information, see the
+++ <p><a href="http://en.wikipedia.org/wiki/AJAX">Ajax</a> is a catchy name for
+++ using JavaScript client-side code that communicates asynchronously with the
+++ server, thus allowing to escape the traditional web model where each button
+++ click translates to a full page reload.</p>
+++
+++ <p>Cocoon Forms has a number of features that allow the building of
+++ highly-interactive forms, such as validation, value-change listeners,
intra-form
+++ actions, repeaters, etc. Having a full page reload for each action doesn't
+++ provide a good user experience and puts an unncessary load on the
server.</p>
+++
+++ <p>Starting with Cocoon 2.1.8, Cocoon Forms offers (mostly) transparent Ajax
+++ support. What this means is that when a form is submitted, this happens in
the
+++ background and only those parts of the form that actually changed are
updated on
+++ the page. Full-page reload only happens when interaction with the form is
+++ finished.</p>
+++
+++ <h1>How to activate Ajax on your forms?</h1>
+++
+++ <h2>The "ajax" attribute</h2>
+++
+++ <p>Activating Ajax mode on your forms is straightforward: just add
+++ <tt>ajax="true"</tt> on the <tt><ft:form-template></tt> element in
your
+++ form template:</p>
+++
+++ <pre><ft:form-template action="continue" method="POST"
<strong>ajax="true"</strong>>
+++ <ft:widget id="email"/>
+++ .../...
+++ </ft:form-template>
+++ </pre>
+++
+++ <p>There are a number of things to take care of though for the Ajax mode to
+++ function properly.</p>
+++
+++ <h2>Use the Template Generator</h2>
+++
+++ <p>As of version 2.1.8, Ajax support is implemented only in the JXTemplate
+++ version of the Forms Template language.</p>
+++
+++ <h2>Container widgets must enclose a container element</h2>
+++
+++ <p>The Ajax support of Cocoon Forms works by sending partial page updates
to the
+++ browser. This requires the representation of widgets to be contained in a
single
+++ element, which becomes the "replacement unit" for that widget.</p>
+++
+++ <p>The styling stylesheets take care of this for terminal widgets such as
fields
+++ and actions, but not for container widgets whose layout are completely
defined
+++ by the page template. Concretely, this means that
<tt><ft:repeater></tt>,
+++ <tt><ft:group></tt> and <tt><ft:union</tt>> instructions must
+++ contain a single element such as HTML <tt><div></tt>,
+++ <tt><able></tt>, <tt><span></tt>, etc.</p>
+++
+++ <pre><ft:group id="info">
+++ <div>
+++ <p><ft:widget id="foo"/></p>
+++ <p><ft:widget id="bar"/></p>
+++ </div>
+++ </ft:group>
+++ </pre>
+++
+++ <p>The formatting pipeline with then take care of adding an <tt>id</tt>
+++ attribute on the container element so that it can be found and updated in
the
+++ displayed page.</p>
+++
+++ <h2>Use <ft:repeater> instead of <ft:repeater-widget></h2>
+++
+++ <p>A problem with the existing <tt><ft:repeater-widget></tt>
instruction
+++ is that it handles two different kinds of widgets, the repeater itself and
its
+++ rows. This has the drawback of not allowing individual refresh of rows and
does
+++ not allow the template system to identify a unique element that contains the
+++ repeater, as explained above.</p>
+++
+++ <p>Starting with Cocoon 2.1.8, the template for repeaters involve two
+++ instructions, <tt><ft:repeater></tt> and
+++ <tt><ft:repeater-rows></tt>:</p>
+++
+++ <ul>
+++ <li><tt><ft:repeater></tt> starts the repeater template, and sets the
+++ repeater as the context widget. This instruction must contain a single
element.
+++ </li>
+++ <li><tt><ft:repeater-rows></tt> iterates through all rows in the
repeater.
+++ Again, and because a row is a container widget, this instruction must
contain a
+++ single element. Note that <tt><ft:repeater-rows></tt> has to be a
+++ descendant of <tt><ft:repeater></tt>, but does not need to be a direct
+++ child and that any number of document elements can enclose
+++ <tt><ft:repeater-rows></tt> (not form templates instruction
though).</li>
+++ </ul>
+++
+++ <p>Remember also that the JXTemplate macros define the <tt>repeater</tt> and
+++ <tt>repeaterLoop</tt> variables in <tt><ft:repeater></tt> and
+++ <tt><ft:repeater-rows></tt> respectively that allow for some powerful
+++ conditional templates.</p>
+++
+++ <p>Here's a complete example, which is what you will have in many real-world
+++ situations:</p>
+++
+++ <pre>Here are your contacts:
+++
+++ <ft:repeater id="contacts">
+++ <jx:choose>
+++
+++ <!-- formatting of an empty "contacts" -->
+++ <jx:when test="${repeater.size == 0}">
+++ <span>
+++ You have no contacts.
+++ <ft:widget id="../add-contact"/>
+++ </span>
+++ </jx:when>
+++
+++ <!-- formatting for a non-empty "contacts" -->
+++ <jx:otherwise>
+++ <div>
+++ <table>
+++ <tr>
+++ <th>First name</th><th>Last
name</th><th>Email</th>
+++ </tr>
+++ <ft:repeater-rows>
+++ <!-- container element for rows -->
+++ <tr class="row-${repeaterLoop.index % 2}">
+++ <ft:widget id="firstname"/>
+++ <ft:widget id="lastname"/>
+++ <ft:widget id="email"/>
+++ <ft:widget id="select"/>
+++ </tr>
+++ </ft:repeater-rows>
+++ </table>
+++ <ft:widget id="../add-contact"/>
+++ <ft:widget id="../delete-contact"/>
+++ </div>
+++ </jx:otherwise>
+++
+++ </jx:choose>
+++ </ft:repeater>
+++
+++ <ft:widget id="ok"/>
+++ </pre>
+++
+++ <p>This example shows some conditional formatting (using JXTemplate)
depending
+++ if the repeater is empty or not. In the two cases, the action widgets that
allow
+++ to remove and delete rows are added within the repeater template. We use the
+++ <tt>"../add-contact"</tt> notation (<tt>"../"</tt> goes back to the parent
+++ widget) as these actions are defined as siblings of the repeater in the form
+++ definition, but we want them to be included in the repeater's conditional
+++ templates. We therefore need to "escape" the repeater to lookup its
siblings.
+++ </p>
+++
+++ <p>Notice the <tt><span></tt> element when the repeater is empty.
Even it
+++ we don't really need it from the page layout point of view, it is required
to
+++ have a single element for Ajax updates when the user adds a contact.</p>
+++
+++ <p>Notice also the <tt><div></tt> element when the repeater is not
empty.
+++ We cannot use the <tt><table></tt> that encloses rows, as again, we
want
+++ to include the <tt>"add-contact"</tt> and <tt>"delete-contacts"</tt>
actions in
+++ the conditional template. We therefore need an enclosing element for the
table
+++ and the actions.</p>
+++
+++ <p>The <tt><ft:repeater-rows></tt> doesn't need anything special as
the
+++ <tt><td></tt> serves as the container. The
+++ <tt>class="row-${repeaterLoop.index % 2}"</tt> allows the generation of
+++ alternating colors of rows, as even rows will have <tt>class="row-0"</tt>
and
+++ odd rows will have <tt>class="row-1"</tt>.</p>
+++
+++ <h2>Using Ajax in portals and aggregations</h2>
+++
+++ <p>Portals do a lot of URL rewriting to ensure that only aggregated portal
pages
+++ are displayed, even if individual portlets use their own URLs without caring
+++ about being integrating in a portal. This rewriting defeats the Ajax system
that
+++ posts the form in the background using the <tt><form></tt>'s
+++ <tt>action</tt> attribute, which is rewritten by the portal.</p>
+++
+++ <p>To allow the Ajax system to function in a portal, you must add an
additional
+++ <tt>ajax-action</tt> attribute on <tt><ft:form-template></tt>. When
+++ present, this attribute's value is where Ajax requests will be posted
instead of
+++ the value of <tt>action</tt>.</p>
+++
+++ <pre><ft:form-template action="aggregation"
ajax-action="continue-form">
+++ .../...
+++ </ft:form-template></pre>
+++
+++ <p>Note that because of the portal's URL rewriting, the two attributes will
+++ often have the same values in the template.</p>
+++
+++ <h1>The form display pipeline for Ajax</h1>
+++
+++ <p>TBC</p>
+++
+++ <p>You can also find additional information in the
<a href="http://www.cocoongt.org/Slides-and-recordings.html">Ajax
presentation
from the Cocoon GetTogether 2005</a>.</p>
(2 equal lines skipped)
Fields
======
no changes
Links
=====
no changes
Custom Fields
=============
no changes
Collections
===========
no changes