cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <>
Subject Transparent and automatic AJAX support for CForms
Date Thu, 14 Apr 2005 13:19:33 GMT
Hi all,

I've been thinking for a few weeks to add AJAX support to CForms. Ajax 
is the current buzzword in the blogosphere since Google maps [1] started 
and the folks at Adaptivepath found this name for the XmlHttpRequest + 
JS + XML combo [2].

At first this looked like a complex problem, requiring a special 
controller and special pipelines on the server to answer ajax requests, 
and "ajax-aware" implementations of widget styling (i.e. having a JS 
client-side part to handle page update). Lots of code for the 
infrastructure, and lots of browser-dependent code each time we want to 
add a new styling.

Then a few days ago I realized that we don't need that complexity. Form 
widgets have all the information needed to inform the surrounding 
environment if they need to be updated, and we can use this information 
to do partial updates of the browser page.

Two days hacking, most of which dedicated to writing client-side JS and 
solving cross-browser compatibility problems and here we are: adding 
ajax="true" on <ft:form-template> turns on the magic.

This is still experimental though: it's only implemented with the 
JXTemplate version of the CForms template language and requires a few 
changes on repeater templates.

                                -- oOo --

How does this work? The idea is, when answering and Ajax request, to 
send back an XML document containing browser updates directives, that 
will contain document fragments that will replace their existing 
counterpart in the page, based on the element id.

These directives are represented by "bu:replace" elements (bu = browser 
update) holding the id of the page element that needs to be replaced. 
This is a very generic mechanism that at this point isn't specifically 
related to CForms. This could for example probably be used by the portal 
to update coplet contents.

Now CForms. When a widget is updated in some way (new value, selection 
list changed, repeater row added or moved, union case updated, etc), it 
registers itself in a list of updated widgets in the Form object.

The template works as usual unless there is a special "cocoon-ajax" 
parameter, indicating an ajax request from the browser. In that case, 
widgets that have changed are enclosed in a "bu:replace" element, 
holding the widget id.

This mix of template structure, and widget instances surrounded by 
bu:replace elements goes to styling, which replaces widget instances by 
their HTML styling, still in the bu:replace elements.

A new "browser-update" transformer flattens the "bu:replace" elements, 
i.e it removes all surrounding markup produced by the template. We now 
have a list of partial page updates that are serialized as XML.

On the brower, the update directives are "played" and the page is 
updated. And that's all.

                                -- oOo --

Any widget, any styling can now be managed this way. The only -- but 
important -- constraint is that the html produced for a widget instance 
need to have the same id attribute as the widget.

This constraint is satisfied for all field stylings (I updated the 
stylesheets), but not always for containers (repeaters, structs, etc).

About repeater, this requires a change in the template language, to 
separate the repeater itself from the iteration on its rows. So rather than:
    <!-- header -->
    <ft:repeater-widget id="myrepeater">
        <!-- row -->

we now have to write:
  <ft:repeater id="myrepeater">
      <!-- header -->
        <!-- row -->

I have turned on ajax mode on the following samples:
- http://localhost:8888/forms-samples/carselector
- http://localhost:8888/forms-samples/do-dynaRepeater.flow
- http://localhost:8888/forms-samples/do-datasourceChooser.flow
- http://localhost:8888/forms-samples/do-taskTree.flow

                                -- oOo --

Next steps are better handling of container widgets and finer-grained 
browser update for some often-used stylings such as dropdowns and inputs.

Now that Cocoon has Spring and Ajax support, we really should post an 
article on TSS ;-)



Sylvain Wallez                        Anyware Technologies  
Apache Software Foundation Member     Research & Technology Director

View raw message