You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by "Edouard sur edouardmercier.fr" <ed...@edouardmercier.fr> on 2008/09/25 18:50:37 UTC

Creating inner components on the fly in a form custom component

Hello.

I've been digging the web with no success, but I'm a Tapestry 5 newbie
(running the v5.0.15), thus maybe I missed something.

I'm currently attempting to develop a custom Tapestry component that
aims at inserting HTML "select/checkbox/textfield" tags into an
existing HTML form. Let's say that I have a .tml which contains a
<t:form>, in which I have my <t:myCustomComponent> element.

This myCustomComponent component is supposed to render multiple HTML
"select/checkbox/textfield" elements, depending on its main Tapestry
parameter. But, instead of writing plain HTML via the traditional
"beginRender/afterRender()" methods, I'd prefer to re-user the
built-in "Select/CheckBox/TextField" Tapestry classes, and add
instances of those classes as inner components of my myCustomComponent
component.

The idea is, on the enclosing form submission, to be able to retrieve
the values of those various HTML form sub elements. I do not know
whether this is feasible. Is it possible to add components on-the-fly
to an existing component during its rendering process (or at another
relevant moment)? I do not even know where to start with. Could
someone, please give me a hint on how to achieve that?

Thank you for your help and time. Cheers,
Édouard

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Creating inner components on the fly in a form custom component

Posted by "Edouard sur edouardmercier.fr" <ed...@edouardmercier.fr>.
Just to let you know that I've found a solution to my problem,
regarding the generation of HTML form elements on the fly.

The idea is not to resort to the B-Bean class set/getValue() methods,
but to define them at the level of the A component class: and in the
core of the method, use the "theAcceptableValue" property argument
that is used inside the A.tml template. This works like a charm.

I've included the modified working example. Hope this will help
someone... Cheers, �douard

Re: Creating inner components on the fly in a form custom component

Posted by "Edouard sur edouardmercier.fr" <ed...@edouardmercier.fr>.
After half a day of struggle, I come back to your expertise.

I have attached a zip/sample of what I intend to do.

I've been attempting to address my dynamic form generation through an
inner Tapestry component named C, which is made of a .java/.tml pair.

This C component takes a string parameter, which contains the
information of the various form elements it should create (a
proprietary XML format), which is interpreted on the fly during the
"C::setupRender()" method. The C.java class injects a
ComponentResources, which is, as I guess mandatory if you want the
corresponding component .tml to be taken into acount (by the way, I
could not find any information about components that present both a
.java and a .tml: if someone has some pointers, I am very
interested...).

This "C::setupRender()" method  instantiates a bean of type "R"
attribute (which is marked with @Persist in the A class), let's call
it "r". It then parses my XML string parameter, and instantiates an
attribute which is a list named "l" (of type java.util.List,  (which
is also marked with @Persist in the A class) of inner static beans "B"
that publish some properties which are going to be used by the A.tml.
Each of these beans (belonging to the l-list) is given at construction
time a reference to the A r attribute , which is stored as a
"s"-attribute of the B-bean, and which will be used later on, during
the form submission process. The .tml iterates through this l-list via
a <t:loop> statement: inside this loop, I do some branching depending
on some properties of the B-bean, so that I can create
<t:radiogroup>/<t:textedit>... So far, so good, the page renders
exactly as I wish, and this makes the generation of a dynamic HTML
form (using the built-in Tapestry form elements).

My problem arises at form submission. My previous component is used
inside a P.tml page which uses a <t:form> (that also contains a
<t:submit> element): before the using P-page reaches the
"P::onSuccess()" method corresponding to the form submission, the
generated-on-the-fly <t:radiogroup> value setters are properly called
(it seems that due to serialization, their reference have changed),
but their R-bean "s"-attribute "point" to another instance than "r".
Hence, this prevents me from updating the A "r"-bean properly, since I
lost its reference.

I tried so many combinations, in order to come this around:  just in
vane. I tried to address the problem the other way round, by providing
a persistent attribute on the B-bean, which stores the result of the
<t:radiogroup> element: the problem is that the "l"-list elements seem
to refer new B objects, no the one that were used during the
"setupRender" method.

I infer that this does not seem to be the right way of generating
forms on the fly (i.e. dynamically). As Kris points it out, I've tried
to understand the Tapestry BeanEditor class, but to be honest it
involves such a deep internal understanding of the Tapestry engine,
that I prefer not to investigate too much time (is a framework like
Tapestry not supposed to relief the developer from focusing on his
requirements?).

I'm stuck at the moment, and have no more idea on how to address a
dynamical form submission in Tapestry. If someone can help me, I would
be so grateful.

Thank you for your time, patience, and support. Regards,
�douard

Re: Creating inner components on the fly in a form custom component

Posted by "Edouard sur edouardmercier.fr" <ed...@edouardmercier.fr>.
Thank you so much Kris for your answer.

The Tapestry 5 BeanEditor source code gives some kind of vertigo, but
I will look at it, in order to better understand what you mean.

In the meantime, I had another idea: using some .tml inside my
component with a <t:loop> and <t:if> statements inside that nest some
<t:select>/<t:radioGroup>...: I think that it might solve my problem
(do you agree?). As soon as I have something which works, I will let
you know.

Cheers,
Édouard

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Creating inner components on the fly in a form custom component

Posted by Kristian Marinkovic <kr...@porsche.co.at>.
hi,

you cannot create T5 components dynamically .... but you can simulate it 
:)

you can define Blocks with any (nested) T5 components and HTML fragments 
that can be re-used multiple times to render a page.

take a closer (source code) look at the BeanEditor. it creates input 
fields
for every property of a given bean. it has a loop with a delegate in it 
which 
is able to render any block that was determined for the current property.
eg. for every String property it will render a block with a TextField 
component
for every Date property it will render a block containing the DateField 
compoinent
...

i hope this helped

g,
kris




"Edouard sur edouardmercier.fr" <ed...@edouardmercier.fr> 
Gesendet von: the.edouard.mercier@gmail.com
25.09.2008 18:50
Bitte antworten an
"Tapestry users" <us...@tapestry.apache.org>


An
users@tapestry.apache.org
Kopie

Thema
Creating inner components on the fly in a form custom component







Hello.

I've been digging the web with no success, but I'm a Tapestry 5 newbie
(running the v5.0.15), thus maybe I missed something.

I'm currently attempting to develop a custom Tapestry component that
aims at inserting HTML "select/checkbox/textfield" tags into an
existing HTML form. Let's say that I have a .tml which contains a
<t:form>, in which I have my <t:myCustomComponent> element.

This myCustomComponent component is supposed to render multiple HTML
"select/checkbox/textfield" elements, depending on its main Tapestry
parameter. But, instead of writing plain HTML via the traditional
"beginRender/afterRender()" methods, I'd prefer to re-user the
built-in "Select/CheckBox/TextField" Tapestry classes, and add
instances of those classes as inner components of my myCustomComponent
component.

The idea is, on the enclosing form submission, to be able to retrieve
the values of those various HTML form sub elements. I do not know
whether this is feasible. Is it possible to add components on-the-fly
to an existing component during its rendering process (or at another
relevant moment)? I do not even know where to start with. Could
someone, please give me a hint on how to achieve that?

Thank you for your help and time. Cheers,
Édouard

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org