Re: T5 Component Info Passing
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
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
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
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
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
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
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
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
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]