You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by BURGHARD Éric <er...@systheo.com> on 2005/09/15 11:59:30 UTC

AJAX + FormsGenerator

Hi,

Since i'm using xsl2 for all my forms, i'm looking for a way to enable ajax
in FormsGenerator. After quickly looking through sources, i found that this
feature seems to be planned in the FormsGenerator (FIXME comments).

At first glance, i thought that this would be just a matter of copy and
paste of the relevant code from JXMacrosHelper to AbstractWidget, so i
could use the browser-update transformer (exactly like we use to do with
the CForms macros). But by reading the comment (we may want to strip out
completely widgets that aren't updated when in AJAX mode), i'm not sure if
this is the right way to do it.

Will the generator generate the bu tags, or will it generate the tags for
updated widgets only (without bu) ?

I need some enlightment just to be able to contribute cleanly to this really
cool feature (thx sylvain).

Regards.




Re: AJAX + FormsGenerator

Posted by BURGHARD Éric <er...@systheo.com>.
Sylvain Wallez wrote:

>>Since i'm using xsl2 for all my forms, i'm looking for a way to enable
>>ajax in FormsGenerator.
>>
> 
> Interesting. Can you explain how you use XSLT 2 and the FormGenerator?
>

Of course. For now it's not exactly compatible with the template language.
The main difference concern repeaters. I declare my templates enclosed in a
variable 'template' like this:

---
<xsl:include href="stylesheets/forms/forms.xsl"/>

<xsl:variable name="template">
  <ft:form-template action="{$continuation}.continue" method="post"
enctype="multipart/form-data">
    ...
    <ft:widget id="maintab_state">
      <fi:styling type="hidden"/>
    </ft:widget>
    ...
    <ft:repeater-size id="myrepeater"/>

    <!--<ft:repeater-widget id="myrepeater">-->
    <xsl:for-each select="ft:repeater-rows('myrepeater')">
      <xsl:variable name="row" select="ft:row-prefix('myrepeater',
position())"/>
      <ft:widget id="{$row}roomarea">
        <fi:styling size="2"/>
      </ft:widget>
    </xsl>
</xsl:variable>
---

As you see it's not as clean as jx syntax, but writing a metastylesheet to
transform <ft:repeater> in an xsl loop and prefix all widgets id seems
quite simple (still efficient with cache and precompilation).

widgets are indexed on their id attribute to speedup lookups. forms.xsl is
pretty simple :

---
    <xsl:param name="continuation"/>
 
    <xsl:key name="widgets" match="fi:*" use="string(@id)"/>
    <xsl:variable name="widgets"
select="/fi:form-generated/fi:form[1]/fi:widgets//*[@id]"/>
    <!-- -->
    <xsl:template match="/">
        <xsl:apply-templates select="$template/page"/>
    </xsl:template>
    <!-- -->
    <xsl:function name="ft:repeater-rows" as="node()*">
        <xsl:param name="id"/>
        <xsl:sequence select="ft:widget($id)/fi:repeater-row"/>
    </xsl:function>
    <!-- -->
    <xsl:template match="ft:widget">
        <xsl:variable name="widget" select="ft:widget(@id)"/>
        <xsl:element name="{name($widget)}">
            <xsl:sequence select="$widget/@* | $widget/*"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
---

Things look suboptimal (use of variables, 2x evaluation of $template), but
for my case (lot of xpath processing in big templates) it's still faster
than jx (with saxon8). However this is temporary stuff. I found a way to
remove the

<xsl:apply-templates select="$template/page"/> 

and replace the

<xsl:variable name="template">

by a

<xsl:template match="/">

and make lookups of widgets directly on input (get rid of this 'widgets'
variable), but it means to replace all

<ft:..>

with something like

<xsl:sequence select="ft:..()"/>

which is less readable (style will be handled via attribute-sets given as
parameters to ft functions in that case). Just need some time to implement.

What was important from now was speed and stability. Readability will come
with meta-stylesheet and i think that the syntax will finally be very close
from jx macros.

> 
> I guess you're referring to the FIXME in
> AbstractWidget.generateSaxFragment.
> 

yes

>>Will the generator generate the bu tags, or will it generate the tags for
>>updated widgets only (without bu) ?
>>  
>>
> 
> If Widget.generateSaxFragment() was producing the bu:replace elements,
> then that would mostly translate to piping the result of the
> FormsGenerator through the BUTransformer.
> 
> Unfortunately, this is not what happens and it should not happen as the
> <bu:replace> tag is really a view concern.
> 

I'm agree.

> A way to achieve this is for widgets to produce an additional
> updated="true" attribute when they were updates. The FormsGenerator can
> then easily wrap such widget elements with a <bu:replace> that can then
> be consumed by the BUTransformer and whatever comes next.
> 

It's clear. I will try to implement it. Our forms are so fat (this is a
feature :-) that ajax for me is not an option :-)

> 
> Hope this helped :-)
> 
> Sylvain
>

yep.

Regards.



Re: AJAX + FormsGenerator

Posted by Sylvain Wallez <sy...@apache.org>.
BURGHARD Éric wrote:

>Hi,
>
>Since i'm using xsl2 for all my forms, i'm looking for a way to enable ajax
>in FormsGenerator.
>

Interesting. Can you explain how you use XSLT 2 and the FormGenerator?

>After quickly looking through sources, i found that this
>feature seems to be planned in the FormsGenerator (FIXME comments).
>  
>

I guess you're referring to the FIXME in AbstractWidget.generateSaxFragment.

>At first glance, i thought that this would be just a matter of copy and
>paste of the relevant code from JXMacrosHelper to AbstractWidget, so i
>could use the browser-update transformer (exactly like we use to do with
>the CForms macros). But by reading the comment (we may want to strip out
>completely widgets that aren't updated when in AJAX mode), i'm not sure if
>this is the right way to do it.
>
>Will the generator generate the bu tags, or will it generate the tags for
>updated widgets only (without bu) ?
>  
>

If Widget.generateSaxFragment() was producing the bu:replace elements, 
then that would mostly translate to piping the result of the 
FormsGenerator through the BUTransformer.

Unfortunately, this is not what happens and it should not happen as the 
<bu:replace> tag is really a view concern.

A way to achieve this is for widgets to produce an additional 
updated="true" attribute when they were updates. The FormsGenerator can 
then easily wrap such widget elements with a <bu:replace> that can then 
be consumed by the BUTransformer and whatever comes next.

>I need some enlightment just to be able to contribute cleanly to this really
>cool feature (thx sylvain).
>  
>

Hope this helped :-)

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://people.apache.org/~sylvain     http://www.anyware-tech.com
Apache Software Foundation Member     Research & Technology Director