Sylvain Wallez wrote:
Hi all,
I'm currently working on adding a "Cocoon suggest" feature to CForms
fields based on Scriptaculous [1]. This requires to associate an URL to
the field to fetch the suggestion list using Ajax requests when the user
inputs something.
Question is: where and how do we specify this? Is this a concern of the
form definition, or a particular styling of the field?
Concretely, should it be
<fd:field id="foo">
<fd:suggestion-list url="foo-suggest">
</fd:field>
or
<ft:widget id="foo">
<fi:styling suggest-href="foo-suggest">
</ft:widget>
It seems more natural at first to add this to the definition, but the
url attribute must define an externally addressable url providing markup
suited to the particular implementation of the suggestion (in the
current case, it's a <li> with special classes). It is therefore more
related to the view. Also, we may consider that the simple fact that we
want to autocomplete is a view concern.
Hmm...
Another solution would be for the suggestion list in the definition to
be given using the same syntax as <fd:selection-list> and have a
system-provided default pipeline to render the list:
<fd:field id="foo">
<fd:suggestion-list src="cocoon:/foo-suggestion-list"/>
<!-- or use whatever implementation of selection list you want -->
</fd:field>
This will automatically generate a
<fi:styling suggest-href="_cforms-suggest-foo"/>
which will be answered to in the sitemap with something like:
<map:match pattern="_cforms-suggest-*">
<map:generate type="jx"
src="resource://org/apache/cocoon/forms/system/generate-suggest-list.xml"/>
<map:transform
src="resource://org/apache/cocoon/forms/system/list2html.xsl"/>
<map:serialize type="xml"/>
</map:match>
This approach still allows to specify the suggest-href only in the view
for cases where it's considered as being a view-only concern, and it
also allows to specify different renderings of the suggestion list by
catching the "_cforms-suggest-xxxx" pattern before the generic
"_cforms-suggest-*".
WDYT?
I don't understand why we need a whole separate pipeline for generating
and rendering the suggestion list. Is responding to an AJAX request for
a suggestion list any different really than any other CForms AJAX
request? The pipeline used by Form.showForm() already has the
capability (if set up for AJAX) to whittle down the widgets' XML to just
what needs to be updated and transform it into the final view format.
It seems that's everything we would need.
Put more concretely:
The suggestion list would be declared in the form definition, just like
a suggestion list. We could even possibly reuse all the existing
SelectionListBuilders to create the suggestion lists. The difference
between the two would be that the selection list is always
Auto-suggest would be turned on in the view with a suggest="true"
styling attribute, much like the ajax="true" attribute on the
form-template element. When this attribute is present, the XSLT adds
the appropriate onkeypress listener, which sends an AJAX request to the
continuation consisting only of that field's name-value pair and a
special parameter (cocoon-ajax-suggest or similar) indicating the desire
to get a suggestion list back.
The form model interprets this request by generating the appropriate
suggestions into the XML, surrounded by a special BrowserUpdate element
such as <bu:suggest/>. All the rest of the XML gets removed by the
BrowserUpdate transformer (just like any other AJAX request), and the
resulting snippet is transformed by the field-styling XSLT into the
final format expected by the view. The client-side script takes this
response and renders it into a suggestion popup.
I think this is closest to your last suggested solution above, in that
it can use any of the existing selection-list builders, but it
eliminates the need for a specialized pipeline. Seems cleaner to me,
though I'm not sure about performance impact. Just another possibility.
--Jason