Re: T5 Component Info Passing

2007-08-06 Thread Todd Orr
I threw a blog together and posted a short tutorial here
(http://blog.torr.redijedi.com/2007/08/t5-tab-component.html). The
code as well as a jar is available through the links there. Hope
someone finds this useful. I've got a couple other components that
I'll probably end up throwing up there too.

On 8/1/07, Francois Armand [EMAIL PROTECTED] wrote:
 Todd Orr wrote:
  [...] This is where I
  found Environment to be deficient. It seems that no matter what
  combination of phases of rendering I use I cannot get the data back to
  the tabnavigation before it is finished rendering and therefore cannot
  alter it's display.
 Not sure that it matches what you want to do, but you could make your
 tabpanel register themselves to an environment value init ialized in
 tabgoup and read this env value in tabnavigation. Something like that :
 (Sorry for the long post, I put all the code)

 ==

 The enclosing element, for my test its a page (your tabgroup)
 8--
 TestRegister.html
 8-
 ?xml version=1.0 encoding=UTF-8 ?
 !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN
 http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd;
 html xmlns=http://www.w3.org/1999/xhtml;
 xmlns:t=http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;
 head
 meta http-equiv=Content-Type content=text/html;
 charset=UTF-8 /
 titleRegister and print ids/title
 /head
 body

 t:printregistered/
 t:registerid t:id=foo/
 t:registerid t:id=bar/
 t:registerid/
 t:printregistered/

 /body
 /html
 8--
 If you call contexturl/testregister, you see :
 8--

 No id registered in env

 I'm foo and should be registered.

 I'm bar and should be registered.

 I'm registerid and should be registered.

 Found these ids in env:

 * Found: foo
 * Found: bar
 * Found: registerid

 8--

 ==
 ==
 Now, the details :

 TestRegister.java
 8-
 public class TestRegister {
 @Inject
 private Environment environment;
 private Register register;
 private String id;

 public String getId() {
 return this.id;
 }

 public void setId(String id) {
 this.id = id;
 }

 @SetupRender
 void initEnv() {
 register = new Register();
 environment.push(Register.class, register);
 }

  @CleanupRender
 void cleanup() {
 environment.pop(Register.class);
 }

 public ListString getIds() {
 return this.register.getRegistered();
 }

 }
 8-

 The register object is really just here as a data container:
 8--
 Register.jeva
 8
 public class Register {
 private ListString registered;

 public Register() {
 registered = new ArrayListString();
 }

 public void register(String id) {
 this.registered.add(id);
 }

 public ListString getRegistered() {
 return this.registered;
 }
 }
 8--


 Component that need to register themselves (your tabpanels) :
 8--
 RegisterId.java :
 8
 public class RegisterId {
 @Environmental
 private Register register;

 @Inject
 private ComponentResources resources;

 @SetupRender
 void setup() {
 if(register != null) {
 this.register.register(resources.getId());
 }
 }

 public String getId() {
 return resources.getId();
 }
 }
 8
 RegisterId.html
 8-
 p xmlns:t=http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;
 t:if test=id
 I'm ${id} and should be registered.
 t:parameter name=else
 I have no id and sould not be registered.
 /t:parameter
 /t:if
 /p
 8--

 ==

 The component that need to read registered ids (your tabnavigation)
 8--
 PrintRegistered.java
 8-
 public class PrintRegistered {

 @Environmental
 private Register 

Re: T5 Component Info Passing

2007-08-01 Thread Francois Armand

Todd Orr wrote:

[...] This is where I
found Environment to be deficient. It seems that no matter what
combination of phases of rendering I use I cannot get the data back to
the tabnavigation before it is finished rendering and therefore cannot
alter it's display.
Not sure that it matches what you want to do, but you could make your 
tabpanel register themselves to an environment value init ialized in 
tabgoup and read this env value in tabnavigation. Something like that :

(Sorry for the long post, I put all the code)

==

The enclosing element, for my test its a page (your tabgroup)
8--
TestRegister.html
8-
?xml version=1.0 encoding=UTF-8 ?
!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN 
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd;
html xmlns=http://www.w3.org/1999/xhtml; 
xmlns:t=http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;

   head
   meta http-equiv=Content-Type content=text/html; 
charset=UTF-8 /

   titleRegister and print ids/title
   /head
   body

   t:printregistered/
   t:registerid t:id=foo/
   t:registerid t:id=bar/
   t:registerid/
   t:printregistered/
  
   /body

/html
8--
If you call contexturl/testregister, you see :
8--

No id registered in env

I'm foo and should be registered.

I'm bar and should be registered.

I'm registerid and should be registered.

Found these ids in env:

   * Found: foo
   * Found: bar
   * Found: registerid

8--

==
==
Now, the details :

TestRegister.java
8-
public class TestRegister {
   @Inject
   private Environment environment;
   private Register register;
   private String id;
  
   public String getId() {

   return this.id;
   }

   public void setId(String id) {
   this.id = id;
   }

   @SetupRender
   void initEnv() {
   register = new Register();
   environment.push(Register.class, register);
   }
  
@CleanupRender

   void cleanup() {
   environment.pop(Register.class);
   }
  
   public ListString getIds() {

   return this.register.getRegistered();
   }
  
}

8-

The register object is really just here as a data container:
8--
Register.jeva
8
public class Register {
   private ListString registered;
  
   public Register() {

   registered = new ArrayListString();
   }

   public void register(String id) {

   this.registered.add(id);
   }
  
   public ListString getRegistered() {

   return this.registered;
   }
}
8--


Component that need to register themselves (your tabpanels) :
8--
RegisterId.java :
8
public class RegisterId {
   @Environmental
   private Register register;

   @Inject
   private ComponentResources resources;
  
   @SetupRender

   void setup() {
   if(register != null) {
   this.register.register(resources.getId());
   }
   }
  
   public String getId() {

   return resources.getId();
   }
}
8
RegisterId.html
8-
p xmlns:t=http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;
   t:if test=id
   I'm ${id} and should be registered.
   t:parameter name=else
   I have no id and sould not be registered.
   /t:parameter
   /t:if
/p
8--

==

The component that need to read registered ids (your tabnavigation)
8--
PrintRegistered.java
8-
public class PrintRegistered {

   @Environmental
   private Register register;
  
   private String id;
  
   public ListString getIds() {

   return null == register ? null : register.getRegistered();
   }

   public String getId() {
   return this.id;
   }

   public void setId(String id) {
   this.id = id;
   }
}
8-
PrintRegistered.html
8-
div  xmlns:t=http://tapestry.apache.org/schema/tapestry_5_0_0.xsd;
   t:if test=ids
   pFound these ids in env:/p
   ul
   t:loop source=ids value=id
   

Re: T5 Component Info Passing

2007-07-31 Thread Todd Orr
I've been running my debugger to try to determine what is available to
the components at various points during rendering. As far as I can see
there is very little information provided regarding what other
components exist anywhere else in the page. The only thing I can get
for sure is the Page. However, even drilling back down from that level
shows that the page doesn't even know what components are in it.

I think this would be a valuable addition to T5. Environmental isn't
sufficient in many cases because you can only pass data one way using
this approach. It would be very useful to be able to traverse the
component graph at some point, maybe even before rendering, to setup
any objects that might require cooperation.

Maybe something already exists and I'm missing it. If so, please fill me in.

On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:
 BTW _resources.getComponentModel().getEmbeddedComponentIds() would be
 really really useful if it didn't return an empty list every time
 during my testing. Is there any way for a component to know what it
 contains?

 On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:
  I've found out how to pass data between components so long as it's
  downstream. Is there a way to pass data from a component (B) that is
  physically below another component (A) to component A?
 
  I've found that performing any data passing (per situation above)
  during the RenderSetup, etc. methods using either ComponentResources
  or Environment is useless since the previous components have already
  finished rendering.
 


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: T5 Component Info Passing

2007-07-31 Thread Todd Orr
I absolutely agree that the components should have as loose coupling
as possible. However, from my testing on simple, non-form related,
nested components the components that render later cannot pass any
information to the components that render sooner.

Perhaps a solid example will better illustrate. I found the
TabComponent wiki tutorial to be too cumbersome. So, I started with
how I want to use the component. From this I think I want to be able
to do the following:

t:tabgroup t:id=wizard1
t:tabnavigation /
t:tabpanel t:id=w1_step1
pThis is step 1/p
/t:tabpanel
t:tabpanel t:id=w1_step2
pThis is step 2/p
/t:tabpanel
t:tabpanel t:id=w1_step3
pThis is step 3/p
/t:tabpanel
/t:tabgroup

I was able to easily control which tabpanel gets displayed by passing
a panelActivation status using environmental. That was easy enough.

So, for my next step I wanted the tabnavigation component to
automatically display the links for the tabs. Tabnavigation uses a
loop component to display a number of links from a private list. At
this point id will suffice as the text, etc. until I get comfortable.
Since any number of tabpanels can be added to the tabgroup I needed a
way to pass the information back to the tabnavigation. This is where I
found Environment to be deficient. It seems that no matter what
combination of phases of rendering I use I cannot get the data back to
the tabnavigation before it is finished rendering and therefore cannot
alter it's display.

This is when I decided I'd try to have the tabgroup gather information
about its contained components so that it can pass information between
the tabnavigation and tabpanel components. Alas, I was unable to do so
as (previously stated) tabgroup has no idea what it contains.

Any ideas?

On 7/31/07, Howard Lewis Ship [EMAIL PROTECTED] wrote:
 The design as it stands exists to remove invisible and unwanted
 dependencies.  Component names, ids, types and classes can change ... and
 yet, using Environmental or ASOs to communicate will stand up to many kinds
 of refactorings, large and small.

 Introducing the ability to create arbitrary linkages between components, by
 id, will make applications far less maintainable.  Worse, you'll change
 component A and some seemingly unrelated component B will break.

 If component A is a container of component B, then an Environmental can be a
 bi-directional conduit of communication between them.

 The question is: on an action request (rather than during a render), how to
 Environmentals get set up, since Environmentals are typically linked to
 render phases.  I've already struggled with this issue (i.e., Form needs to
 establish the FormSupport environmental as the components it encloses invoke
 their submit callbacks).

 On 7/31/07, Todd Orr [EMAIL PROTECTED] wrote:
 
  I've been running my debugger to try to determine what is available to
  the components at various points during rendering. As far as I can see
  there is very little information provided regarding what other
  components exist anywhere else in the page. The only thing I can get
  for sure is the Page. However, even drilling back down from that level
  shows that the page doesn't even know what components are in it.
 
  I think this would be a valuable addition to T5. Environmental isn't
  sufficient in many cases because you can only pass data one way using
  this approach. It would be very useful to be able to traverse the
  component graph at some point, maybe even before rendering, to setup
  any objects that might require cooperation.
 
  Maybe something already exists and I'm missing it. If so, please fill me
  in.
 
  On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:
   BTW _resources.getComponentModel().getEmbeddedComponentIds() would be
   really really useful if it didn't return an empty list every time
   during my testing. Is there any way for a component to know what it
   contains?
  
   On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:
I've found out how to pass data between components so long as it's
downstream. Is there a way to pass data from a component (B) that is
physically below another component (A) to component A?
   
I've found that performing any data passing (per situation above)
during the RenderSetup, etc. methods using either ComponentResources
or Environment is useless since the previous components have already
finished rendering.
   
  
 
  -
  To unsubscribe, e-mail: [EMAIL PROTECTED]
  For additional commands, e-mail: [EMAIL PROTECTED]
 
 


 --
 Howard M. Lewis Ship
 TWD Consulting, Inc.
 Independent J2EE / Open-Source Java Consultant
 Creator and PMC Chair, Apache Tapestry
 Creator, Apache HiveMind

 Professional Tapestry training, mentoring, support
 and project work.  http://howardlewisship.com



Re: T5 Component Info Passing

2007-07-31 Thread Nick Westgate

Hi Todd.

The documentation is not exactly clear on this topic, so I'm not sure
whether that or the implementation is incomplete ...

The docs say:
Components inside another components template are called embedded components.

Whereas the implementation WRT getEmbeddedComponentIds() is:
Components DECLARED in component's CLASS are called embedded components.

You can get the list of embedded components if:

1- the TabGroup component has a separate HTML template

TabGroup.html:
t:tabnavigation /
t:tabpanel t:id=step1
...

2- the TabGroup component Java file uses @Component to embed them

TabGroup.java:
...
@Component
private TabPanel step1;

I realize this is not quite what you want, but I hope it helps.

Cheers,
Nick.


Todd Orr wrote:

I absolutely agree that the components should have as loose coupling
as possible. However, from my testing on simple, non-form related,
nested components the components that render later cannot pass any
information to the components that render sooner.

Perhaps a solid example will better illustrate. I found the
TabComponent wiki tutorial to be too cumbersome. So, I started with
how I want to use the component. From this I think I want to be able
to do the following:

t:tabgroup t:id=wizard1
t:tabnavigation /
t:tabpanel t:id=w1_step1
pThis is step 1/p
/t:tabpanel
t:tabpanel t:id=w1_step2
pThis is step 2/p
/t:tabpanel
t:tabpanel t:id=w1_step3
pThis is step 3/p
/t:tabpanel
/t:tabgroup

I was able to easily control which tabpanel gets displayed by passing
a panelActivation status using environmental. That was easy enough.

So, for my next step I wanted the tabnavigation component to
automatically display the links for the tabs. Tabnavigation uses a
loop component to display a number of links from a private list. At
this point id will suffice as the text, etc. until I get comfortable.
Since any number of tabpanels can be added to the tabgroup I needed a
way to pass the information back to the tabnavigation. This is where I
found Environment to be deficient. It seems that no matter what
combination of phases of rendering I use I cannot get the data back to
the tabnavigation before it is finished rendering and therefore cannot
alter it's display.

This is when I decided I'd try to have the tabgroup gather information
about its contained components so that it can pass information between
the tabnavigation and tabpanel components. Alas, I was unable to do so
as (previously stated) tabgroup has no idea what it contains.

Any ideas?

On 7/31/07, Howard Lewis Ship [EMAIL PROTECTED] wrote:

The design as it stands exists to remove invisible and unwanted
dependencies.  Component names, ids, types and classes can change ... and
yet, using Environmental or ASOs to communicate will stand up to many kinds
of refactorings, large and small.

Introducing the ability to create arbitrary linkages between components, by
id, will make applications far less maintainable.  Worse, you'll change
component A and some seemingly unrelated component B will break.

If component A is a container of component B, then an Environmental can be a
bi-directional conduit of communication between them.

The question is: on an action request (rather than during a render), how to
Environmentals get set up, since Environmentals are typically linked to
render phases.  I've already struggled with this issue (i.e., Form needs to
establish the FormSupport environmental as the components it encloses invoke
their submit callbacks).

On 7/31/07, Todd Orr [EMAIL PROTECTED] wrote:

I've been running my debugger to try to determine what is available to
the components at various points during rendering. As far as I can see
there is very little information provided regarding what other
components exist anywhere else in the page. The only thing I can get
for sure is the Page. However, even drilling back down from that level
shows that the page doesn't even know what components are in it.

I think this would be a valuable addition to T5. Environmental isn't
sufficient in many cases because you can only pass data one way using
this approach. It would be very useful to be able to traverse the
component graph at some point, maybe even before rendering, to setup
any objects that might require cooperation.

Maybe something already exists and I'm missing it. If so, please fill me
in.

On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:

BTW _resources.getComponentModel().getEmbeddedComponentIds() would be
really really useful if it didn't return an empty list every time
during my testing. Is there any way for a component to know what it
contains?

On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:

I've found out how to pass data between components so long as it's
downstream. Is there a way to pass data from a component (B) that is
physically below another component (A) to component A?

I've found that performing any 

Re: T5 Component Info Passing

2007-07-31 Thread Todd Orr
Since I'd like the number of panels to be configurable by the page
building programmer, having a set number of @Components in my TabGroup
will not work. I've found a workaround for now:

t:tabgroup
div t:type=tabnavigation t:id=nav t:panels=stuff1, stuff2, 
stuff3 /
t:tabpanel t:id=stuff1 elementName=div
pThis is stuff 1/p
/t:tabpanel
div t:type=tabpanel t:id=stuff2
pThis is stuff 2/p
/div
t:tabpanel t:id=stuff3
pThis is stuff 3/p
/t:tabpanel
/t:tabgroup

I've got the navigation working. It's functional. It's just way uglier
than I had hoped. If only there was a way to get those ids dynamically
instead of hardwiring them in the t:panels attribute...

As imperfect as it is, I'll probably post the code after I've tinkered
with the capabilities a little bit.

Thanks all.

On 7/31/07, Nick Westgate [EMAIL PROTECTED] wrote:
 Hi Todd.

 The documentation is not exactly clear on this topic, so I'm not sure
 whether that or the implementation is incomplete ...

 The docs say:
 Components inside another components template are called embedded 
 components.

 Whereas the implementation WRT getEmbeddedComponentIds() is:
 Components DECLARED in component's CLASS are called embedded components.

 You can get the list of embedded components if:

 1- the TabGroup component has a separate HTML template

 TabGroup.html:
  t:tabnavigation /
  t:tabpanel t:id=step1
  ...

 2- the TabGroup component Java file uses @Component to embed them

 TabGroup.java:
  ...
  @Component
  private TabPanel step1;

 I realize this is not quite what you want, but I hope it helps.

 Cheers,
 Nick.


 Todd Orr wrote:
  I absolutely agree that the components should have as loose coupling
  as possible. However, from my testing on simple, non-form related,
  nested components the components that render later cannot pass any
  information to the components that render sooner.
 
  Perhaps a solid example will better illustrate. I found the
  TabComponent wiki tutorial to be too cumbersome. So, I started with
  how I want to use the component. From this I think I want to be able
  to do the following:
 
  t:tabgroup t:id=wizard1
t:tabnavigation /
t:tabpanel t:id=w1_step1
pThis is step 1/p
/t:tabpanel
t:tabpanel t:id=w1_step2
pThis is step 2/p
/t:tabpanel
t:tabpanel t:id=w1_step3
pThis is step 3/p
/t:tabpanel
  /t:tabgroup
 
  I was able to easily control which tabpanel gets displayed by passing
  a panelActivation status using environmental. That was easy enough.
 
  So, for my next step I wanted the tabnavigation component to
  automatically display the links for the tabs. Tabnavigation uses a
  loop component to display a number of links from a private list. At
  this point id will suffice as the text, etc. until I get comfortable.
  Since any number of tabpanels can be added to the tabgroup I needed a
  way to pass the information back to the tabnavigation. This is where I
  found Environment to be deficient. It seems that no matter what
  combination of phases of rendering I use I cannot get the data back to
  the tabnavigation before it is finished rendering and therefore cannot
  alter it's display.
 
  This is when I decided I'd try to have the tabgroup gather information
  about its contained components so that it can pass information between
  the tabnavigation and tabpanel components. Alas, I was unable to do so
  as (previously stated) tabgroup has no idea what it contains.
 
  Any ideas?
 
  On 7/31/07, Howard Lewis Ship [EMAIL PROTECTED] wrote:
  The design as it stands exists to remove invisible and unwanted
  dependencies.  Component names, ids, types and classes can change ... and
  yet, using Environmental or ASOs to communicate will stand up to many kinds
  of refactorings, large and small.
 
  Introducing the ability to create arbitrary linkages between components, by
  id, will make applications far less maintainable.  Worse, you'll change
  component A and some seemingly unrelated component B will break.
 
  If component A is a container of component B, then an Environmental can be 
  a
  bi-directional conduit of communication between them.
 
  The question is: on an action request (rather than during a render), how to
  Environmentals get set up, since Environmentals are typically linked to
  render phases.  I've already struggled with this issue (i.e., Form needs to
  establish the FormSupport environmental as the components it encloses 
  invoke
  their submit callbacks).
 
  On 7/31/07, Todd Orr [EMAIL PROTECTED] wrote:
  I've been running my debugger to try to determine what is available to
  the components at various points during rendering. As far as I can see
  there is very little information provided regarding what other
  components exist anywhere else in the page. The only thing I can 

Re: T5 Component Info Passing

2007-07-31 Thread Nick Westgate

Great. Or put it on the wiki so others can use and improve it.

Cheers,
Nick.


Todd Orr wrote:

As imperfect as it is, I'll probably post the code after I've tinkered
with the capabilities a little bit.

Thanks all.



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



T5 Component Info Passing

2007-07-30 Thread Todd Orr
I've found out how to pass data between components so long as it's
downstream. Is there a way to pass data from a component (B) that is
physically below another component (A) to component A?

I've found that performing any data passing (per situation above)
during the RenderSetup, etc. methods using either ComponentResources
or Environment is useless since the previous components have already
finished rendering.

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: T5 Component Info Passing

2007-07-30 Thread Todd Orr
BTW _resources.getComponentModel().getEmbeddedComponentIds() would be
really really useful if it didn't return an empty list every time
during my testing. Is there any way for a component to know what it
contains?

On 7/30/07, Todd Orr [EMAIL PROTECTED] wrote:
 I've found out how to pass data between components so long as it's
 downstream. Is there a way to pass data from a component (B) that is
 physically below another component (A) to component A?

 I've found that performing any data passing (per situation above)
 during the RenderSetup, etc. methods using either ComponentResources
 or Environment is useless since the previous components have already
 finished rendering.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]