CPS Ajaxification round #2

Thu 05 January 2006 By nuxeo

I really enjoy the graceful degradation approach. It's a pleasure
to enhance CPS user interfaces that way.

Last time the edit form for simple document was ajaxified in order
to give the user a fast way to get feedback when she changes the data.

The next challenging step on these form is to enable file uploads
so complex documents will be ajaxified as well. The iframe technique
is the only technique i've hurd of for this task. Some guys over the Ruby ML
also explained me how to do it with a bit of Flash in the form but this
is a dependency we don't want. Anyway, this enhancement will be exposed
in round #3 or #4.

Round #2 is about a quick and lazy todo, yet powerfull feature: autocompletion.

This is just great: with Scriptaculous there's absolutely nothing to code :).
The well-thaught Ajax.Autocompleter class knows automatically how to grab
an input field and link it to a server-side or a client-side data provider.

The class deals with all the hard work, automatically showing and
hiding the panel that contains the choices. Every command you would think
of to select an element from the list (keyboard, mouse) just works as

I won't expose how all this works, just take a look at this demo and
enjoy their work.

Client-side data or server-side data ?

Like said previously, a decision has to be made when this kind of widgets
are used: where does the data that feeds the popup panel live ?

That's a topic you can talk about for hours with Paul Everitt, who
is a preacher of the full client-side approach. In his demos, Paul loads
data at startup and play with it on the form through javascript.

It's very impressive, as the whole screen can be repainted without calling
the server ever.

If I were working at BuzzwordMakers Corp., I would call this approach
the Lazy Ajax Painting (LAP).

But too much LAPing can deteriorate the user experience: the lag involved
can be really bad, and she might try to refresh the page over and over again,
because it seems locked or some similar feeling.

Furthermore, the retrieved data is dead: if someone else changes it on
the server it won't change on her client browser, unless an expensive observer
that recheck datas once a while is settled.

On the other hand, too much asynchronous server calls can drawn everything
as well...

But autocompletion means the output is beeing filtered out at least by the first
character, so the amount of data is not so bad.

For example, if the widget is used to select some people over a LDAP directory
that contains 5k users, the first data packet will be composed of an average of
200 entries at most. The second character put this number down to 8 entries
or so. In case of a big directory, a smart approach would be to block the
autocompletion feature until the user has typed a few characters.

Anyway, this is the same scale than regular queries over directories, so a full
server-side data provider is probably the way to go in most case.

If needed, the widget can combine both ways, and decide which one to use depending
on the amount of data.

CPSAutoCompletionString widget

Back to CPS: I've created a new widget called CPSAutoCompletionString that is just
a simple String widget with an extra piece of javascript. It adds a class
initialization and roughly renders someting that looks like this:

<input type="text" name="field" id="field" value="cool value"/>
<div id="field_choices"/>
<script type="text/javascript" language="javascript">
new Ajax.Autocompleter("field", "field_choices", "server_method", {});'>

The input will use the div, feeded with value asynchronously retrieved with the
server_method. That's it. cough cough. (Some may argue it's even shorter
in Ruby on Rails, but it looks short enough to me ;) )

Now the cool part: the server method has been kept totally out of the widget code
in order to let the developer code it as he wants. A Zope 3 view can be done,
or a raw Zope 2 skin as well.

The server side has to send a <UL> tag with all entries in it.

Since this javascript code works with the raw responseText, we don't need to
implement a special transport protocol (json, rpc, ..)

The result is just used to fill the div.

Example of Zope 2 skin:


I wish I had Five installed so I would do a view here :')

return '<ul class="cpsskinsMenu"><li>one</li><li>two</li><li>three</li></ul>'

There's no filtering in this example, but it's really simple to send the current
input in order to filter entries, and I'm still working on it.


CPSAutoCompletionString has been integrated for CPS 3.4.0 but won't be used
in any CPS forms yet, as this will be done later on. You can already use it
though, in your custom CPSSchemas layouts, or through CPSTypeMaker.

CPS Developpers, if you give it a try, let me know !

(Post originally written by Tarek Ziadé on the old Nuxeo blogs.)

Category: Product & Development