Re: Best way to extend a component?
Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit : 1.) Extend MySelect from Select I found no way to assign my model to the selects privat model. There is a setModel in Select but it seems to be there only for unit tests. Tapestry components weren't meant to be subclassed. By the way, why that ? It's one thing I felt difficult, for example to change the way the GridPager is displayed (to display the number of pages, number of items), we had to do a big copy paste of the Grid component and the related components, instead of subclassing it. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
I agree. I'm upgrading a big project from tapestry 3 to 5. As I looked into the documentation and sources of tapestry 5 I thought: wow, this is really great. it could not be any better! But if components are no meant to be subclassed this seems like a drawback for me. You have to copy and adjust the code which does not fit into the tapestry world (DRY principle) If you use embedded components to extend a component you need an additional (more or less useless) template file and you come in trouble if you use this component multiple times in a page (because of the embedded components id binding) Anyway, even if there is way to get around these problems with embedded components I described, it would feel more natural for me if I just could subclass a component. Andreas I ended up copying Nicolas Bouillon wrote: Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit : 1.) Extend MySelect from Select I found no way to assign my model to the selects privat model. There is a setModel in Select but it seems to be there only for unit tests. Tapestry components weren't meant to be subclassed. By the way, why that ? It's one thing I felt difficult, for example to change the way the GridPager is displayed (to display the number of pages, number of items), we had to do a big copy paste of the Grid component and the related components, instead of subclassing it. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
I also wish component subclassing was at least an option. What I don't like about copying and pasting from a Tapestry component is that I end up relying on some internal packages and classes. That makes me feel dirty. Benny On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert a...@weberhofer.at wrote: I agree. I'm upgrading a big project from tapestry 3 to 5. As I looked into the documentation and sources of tapestry 5 I thought: wow, this is really great. it could not be any better! But if components are no meant to be subclassed this seems like a drawback for me. You have to copy and adjust the code which does not fit into the tapestry world (DRY principle) If you use embedded components to extend a component you need an additional (more or less useless) template file and you come in trouble if you use this component multiple times in a page (because of the embedded components id binding) Anyway, even if there is way to get around these problems with embedded components I described, it would feel more natural for me if I just could subclass a component. Andreas I ended up copying Nicolas Bouillon wrote: Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit : 1.) Extend MySelect from Select I found no way to assign my model to the selects privat model. There is a setModel in Select but it seems to be there only for unit tests. Tapestry components weren't meant to be subclassed. By the way, why that ? It's one thing I felt difficult, for example to change the way the GridPager is displayed (to display the number of pages, number of items), we had to do a big copy paste of the Grid component and the related components, instead of subclassing it. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Why should you have the same rendering code in two different components? When I have common code for several components I create an abstract base component and put it into the base package. The template is not mandatory for components or abstract base components/pages btw. You can use subclassing whenever you want but that doesn't always makes your code better. If you have common logic in different components you should move it into a service... Well, and I think tapestry can't free you from your dirtyness, you should try soap :) Am 13.05.2010 um 14:28 schrieb Benny Law: I also wish component subclassing was at least an option. What I don't like about copying and pasting from a Tapestry component is that I end up relying on some internal packages and classes. That makes me feel dirty. Benny On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert a...@weberhofer.at wrote: I agree. I'm upgrading a big project from tapestry 3 to 5. As I looked into the documentation and sources of tapestry 5 I thought: wow, this is really great. it could not be any better! But if components are no meant to be subclassed this seems like a drawback for me. You have to copy and adjust the code which does not fit into the tapestry world (DRY principle) If you use embedded components to extend a component you need an additional (more or less useless) template file and you come in trouble if you use this component multiple times in a page (because of the embedded components id binding) Anyway, even if there is way to get around these problems with embedded components I described, it would feel more natural for me if I just could subclass a component. Andreas I ended up copying Nicolas Bouillon wrote: Le 11/05/2010 21:34, Thiago H. de Paula Figueiredo a écrit : 1.) Extend MySelect from Select I found no way to assign my model to the selects privat model. There is a setModel in Select but it seems to be there only for unit tests. Tapestry components weren't meant to be subclassed. By the way, why that ? It's one thing I felt difficult, for example to change the way the GridPager is displayed (to display the number of pages, number of items), we had to do a big copy paste of the Grid component and the related components, instead of subclassing it. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
On Thu, 13 May 2010 09:58:15 -0300, Christian Riedel cr.ml...@googlemail.com wrote: Why should you have the same rendering code in two different components? When I have common code for several components I create an abstract base component and put it into the base package. The template is not mandatory for components or abstract base components/pages btw. You can use subclassing whenever you want but that doesn't always makes your code better. Exactly. I was saying that components provided by Tapestry aren't meant to be subclassed, but the ones you write can be. Tapestry's components use subclassing too: AbstractField, AbstractTextField, etc. Maybe Tapestry should have some more of them, just like an AbstractSelect. If you have common logic in different components you should move it into a service... Nice advice. :) Well, and I think tapestry can't free you from your dirtyness, you should try soap :) No, thank you. :P -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
On Thu, 13 May 2010 06:35:44 -0300, Nicolas Bouillon nico...@bouil.org wrote: By the way, why that ? Compatibility. The more open to subclassing a component is, the harder it is to keep it backward-compatible. It's one thing I felt difficult, for example to change the way the GridPager is displayed (to display the number of pages, number of items), we had to do a big copy paste of the Grid component and the related components, instead of subclassing it. In these cases, what about filing a JIRA about it? -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
By the way, why that ? Compatibility. The more open to subclassing a component is, the harder it is to keep it backward-compatible. Well, that's a good point. It's always about keeping the balance ... Exactly. I was saying that components provided by Tapestry aren't meant to be subclassed, but the ones you write can be. Tapestry's components use subclassing too: AbstractField, AbstractTextField, etc. Maybe Tapestry should have some more of them, just like an AbstractSelect. That would nice! If you have common logic in different components you should move it into a service... Of course! But I'm talking about common component logic like tapestry already provides like Select or Grid. No application releated logic or components which are entirely new. I have created an AbstractSelect which is the baseclass of many of my Subclasses now, but this (my) AbstractSelect is unnecessary and repeats just the code of Select with some minor changes. Andreas - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in subclassing, but closing the door to subclassing for the sake of backward-compatibility may be an overkill IMHO. Everything has pros and cons, and the developer is ultimately responsible for weighing them and choosing what's best for their situation. BTW, if anyone can think of a clean way to solve my problem with the Select component, please let me know. Thanks. Benny On Thu, May 13, 2010 at 8:58 AM, Christian Riedel cr.ml...@googlemail.comwrote: Why should you have the same rendering code in two different components? When I have common code for several components I create an abstract base component and put it into the base package. The template is not mandatory for components or abstract base components/pages btw. You can use subclassing whenever you want but that doesn't always makes your code better. If you have common logic in different components you should move it into a service... Well, and I think tapestry can't free you from your dirtyness, you should try soap :) Am 13.05.2010 um 14:28 schrieb Benny Law: I also wish component subclassing was at least an option. What I don't like about copying and pasting from a Tapestry component is that I end up relying on some internal packages and classes. That makes me feel dirty. Benny On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert a...@weberhofer.at wrote: I agree. I'm upgrading a big project from tapestry 3 to 5. As I looked into the documentation and sources of tapestry 5 I thought: wow, this is really great. it could not be any better! But if components are no meant to be subclassed this seems like a drawback for me. You have to copy and adjust the code which does not fit into the tapestry world (DRY principle) If you use embedded components to extend a component you need an additional (more or less useless) template file and you come in trouble if you use this component multiple times in a page (because of the embedded components id binding) Anyway, even if there is way to get around these problems with embedded components I described, it would feel more natural for me if I just could subclass a component. Andreas I ended up copying - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in subclassing, but closing the door to subclassing for the sake of backward-compatibility may be an overkill IMHO. Everything has pros and cons, and the developer is ultimately responsible for weighing them and choosing what's best for their situation. BTW, if anyone can think of a clean way to solve my problem with the Select component, please let me know. Thanks. Benny On Thu, May 13, 2010 at 8:58 AM, Christian Riedel cr.ml...@googlemail.comwrote: Why should you have the same rendering code in two different components? When I have common code for several components I create an abstract base component and put it into the base package. The template is not mandatory for components or abstract base components/pages btw. You can use subclassing whenever you want but that doesn't always makes your code better. If you have common logic in different components you should move it into a service... Well, and I think tapestry can't free you from your dirtyness, you should try soap :) Am 13.05.2010 um 14:28 schrieb Benny Law: I also wish component subclassing was at least an option. What I don't like about copying and pasting from a Tapestry component is that I end up relying on some internal packages and classes. That makes me feel dirty. Benny On Thu, May 13, 2010 at 7:47 AM, Andreas Bohnert a...@weberhofer.at wrote: I agree. I'm upgrading a big project from tapestry 3 to 5. As I looked into the documentation and sources of tapestry 5 I thought: wow, this is really great. it could not be any better! But if components are no meant to be subclassed this seems like a drawback for me. You have to copy and adjust the code which does not fit into the tapestry world (DRY principle) If you use embedded components to extend a component you need an additional (more or less useless) template file and you come in trouble if you use this component multiple times in a page (because of the embedded components id binding) Anyway, even if there is way to get around these problems with embedded components I described, it would feel more natural for me if I just could subclass a component. Andreas I ended up copying - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
tapestry-hibernate, supplement hibernate.cfg.xml with some code
hi all i'm new to tapestry 5 and have started playing with tapestry-hibernate. in other projects i've used an uncommon approach to configuring tapestry whereby i load most of the configuration via hibernate.cfg.xml, but then add a few more options via code and properties. for example, the general config that doesn't change between different deployment targets is contained in the xml, but deployment specific values such as db url, username and password will come from a separate properties file and then provided to tapestry via Configuration.setProperty. what's the simplest way to achieve something similar in tapestry 5.1 with tapestry-hibernate? thanks, paul. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in subclassing, but closing the door to subclassing for the sake of backward-compatibility may be an overkill IMHO. Everything has pros and cons, and the developer is ultimately responsible for weighing them and choosing what's best for their situation. BTW, if anyone can think of a clean way to solve my problem with the Select component, please let me know. Thanks. Benny
Re: tapestry-hibernate, supplement hibernate.cfg.xml with some code
On Thu, 13 May 2010 08:22:46 -0300, Paul Stanton paul.stan...@gmail.com wrote: hi all Hi! i'm new to tapestry 5 and have started playing with tapestry-hibernate. in other projects i've used an uncommon approach to configuring tapestry whereby i load most of the configuration via hibernate.cfg.xml, but then add a few more options via code and properties. for example, the general config that doesn't change between different deployment targets is contained in the xml, but deployment specific values such as db url, username and password will come from a separate properties file and then provided to tapestry via Configuration.setProperty. what's the simplest way to achieve something similar in tapestry 5.1 with tapestry-hibernate? Contribute a HibernateConfigurer that does what you want: http://tapestry.apache.org/tapestry5.1/tapestry-hibernate-core/conf.html -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in subclassing, but closing the door to subclassing for the sake of backward-compatibility may be an overkill IMHO. Everything has pros and cons, and the developer is ultimately responsible for weighing them and choosing what's best for their situation. BTW, if anyone can think of a clean way to solve my problem with the Select component, please let me know. Thanks. Benny - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in subclassing, but closing the door to subclassing for the sake of backward-compatibility may be an overkill IMHO. Everything has pros and cons, and the developer is ultimately responsible for weighing them and choosing what's best for their situation. BTW, if anyone can think of a clean way to solve my problem with the Select component, please let me know. Thanks. Benny - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beforeRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified showBlankOption() method. It just didn't feel right. I don't think all this talk about capturing common logic in a base class or creating a service for it applies here. In my opinion, a good framework should provide the option for extending its components easily. I believe that with proper design and careful consideration, inheritance can still be very useful. Developers should understand any potential risks involved in
Re: Best way to extend a component?
On Thu, 13 May 2010 15:30:11 -0300, Robert Zeigler robe...@scazdl.org wrote: In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. I was thinking in a mixin too, but in 5.1 and using DOM rewriting. A little more complicated, but still viable. Or just bind the blankOption to a getter that would have the logic there. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
As I explained before, I want to change the auto behavior to make it smarter. Currently, there is really no intelligence in the logic: a blank option is added if the field is not required, and no blank option is added if the field is required. When the option list is static, I can set the blank option myself, no problem. But when the list is dynamic, I don't know ahead of time how many options there will be, so I want the Select component to decide for me. If the field is required, I still want a blank option unless there is exactly one option because I don't want the first option to be selected as a default. I want the user to consciously choose a value. On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler robe...@scazdl.org wrote: Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beforeRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there
Re: Best way to extend a component?
...add some really heavy logic to your page/component: tml: t:form t:select model=options value=o blankOption=prop:blank / t:submit / /t:form page: @Property private String[] options; @Persist @Property private String o; @SetupRender void setup() { options = reallyExpensiveDBQuery(); if (options.length 1) { options = addDefaultToOptions(); } } private String[] addDefaultToOptions() { final String[] result = new String[options.length + 1]; result[0] = ___default___; for (int i = 1; i = options.length; i++) { result[i] = options[i-1]; } return result; } private String[] reallyExpensiveDBQuery() { return new String[] { 1, 2 }; } public String getBlank() { return NEVER; } is that the solution to your problem? Am 13.05.2010 um 20:44 schrieb Benny Law: As I explained before, I want to change the auto behavior to make it smarter. Currently, there is really no intelligence in the logic: a blank option is added if the field is not required, and no blank option is added if the field is required. When the option list is static, I can set the blank option myself, no problem. But when the list is dynamic, I don't know ahead of time how many options there will be, so I want the Select component to decide for me. If the field is required, I still want a blank option unless there is exactly one option because I don't want the first option to be selected as a default. I want the user to consciously choose a value. On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler robe...@scazdl.org wrote: Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beforeRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return
Re: Best way to extend a component?
If the field is required, I still want a blank option unless there is exactly one option because I don't want the first option to be selected as a default. I want the user to consciously choose a value. ...wait. what? if it is required is probably not valid to choose the blank option, right? sounds like a marketing requirement to me... On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler robe...@scazdl.org wrote: Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beforeRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the Select component with a modified
Re: Best way to extend a component?
On Thu, 13 May 2010 15:44:50 -0300, Benny Law benny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Law benny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
tapestry-hibernate, supplement hibernate.cfg.xml with some code
hi all i'm new to tapestry 5 and have started playing with tapestry-hibernate. in other projects i've used an uncommon approach to configuring tapestry whereby i load most of the configuration via hibernate.cfg.xml, but then add a few more options via code and properties. for example, the general config that doesn't change between different deployment targets is contained in the xml, but deployment specific values such as db url, username and password will come from a separate properties file and then provided to tapestry via Configuration.setProperty. what's the simplest way to achieve something similar in tapestry 5.1 with tapestry-hibernate? thanks, paul. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: tapestry-hibernate, supplement hibernate.cfg.xml with some code
Thanks Thiago, I assume you mean this bit: --quote Another way is to contribute objects that perform configuration (such as setting event listeners). Example: public static void contributeHibernateSessionSource(OrderedConfigurationHibernateConfigurer config) { config.add(Widget, new WidgetHibernateConfigurer()); } --end quote By adding, does that override the default configurer or just append to do extras after the default has run? Thanks, p. Thiago H. de Paula Figueiredo wrote: On Thu, 13 May 2010 08:22:46 -0300, Paul Stanton paul.stan...@gmail.com wrote: hi all Hi! i'm new to tapestry 5 and have started playing with tapestry-hibernate. in other projects i've used an uncommon approach to configuring tapestry whereby i load most of the configuration via hibernate.cfg.xml, but then add a few more options via code and properties. for example, the general config that doesn't change between different deployment targets is contained in the xml, but deployment specific values such as db url, username and password will come from a separate properties file and then provided to tapestry via Configuration.setProperty. what's the simplest way to achieve something similar in tapestry 5.1 with tapestry-hibernate? Contribute a HibernateConfigurer that does what you want: http://tapestry.apache.org/tapestry5.1/tapestry-hibernate-core/conf.html - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
this looks very promising!! that is what I was asking for and would solve at least my problem :) So with mixins you do/can not override a method, you build a execution chain instead? Andreas Robert Zeigler wrote: Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beforeRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) { return !isRequired(); } if (options.size() == 0 || value == null) { return true; } if (value != null) { for (OptionModel option: options) { if (option.getValue().equals( value )) { return !isRequired(); } } } return true; } I hope it's clear what I want to achieve with the enhanced logic for AUTO. Regards, Benny On Thu, May 13, 2010 at 10:29 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Does this help at all? http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N Cheers, Geoff On 14/05/2010, at 12:11 AM, Benny Law wrote: We are talking about subclassing a Tapestry component here. To give you an example, I wanted to subclass the Select component to override how BlankOption.AUTO is interpreted. I wanted the logic to not just look at the required property but also to consider how many options are available and whether there is a current value. (I find the current logic lacking because, for example, the first option will always be selected as default if required is true, but there may not be a meaningful default for the field.) All I needed to do was to override the showBlankOption() method, but I couldn't because it's a private method. I ended up making a duplicate of the
Re: tapestry-hibernate, supplement hibernate.cfg.xml with some code
On Thu, 13 May 2010 16:48:07 -0300, Paul Stanton p...@mapshed.com.au wrote: I assume you mean this bit: --quote Another way is to contribute objects that perform configuration (such as setting event listeners). Example: public static void contributeHibernateSessionSource(OrderedConfigurationHibernateConfigurer config) { config.add(Widget, new WidgetHibernateConfigurer()); } --end quote Exactly! By adding, does that override the default configurer or just append to do extras after the default has run? It doesn't override, as configurers are run. Note that it is an OrderedConfiguration, so you can put your configurer to run before or after the other ones. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnert a...@weberhofer.at wrote: this looks very promising!! that is what I was asking for and would solve at least my problem :) So with mixins you do/can not override a method, you build a execution chain instead? In a simplified view, mixins work like you had copied their methods to the component or page to which the mixin is applied. I wouldn't say it's an execution chain. This sounds more similar to Tapestry-IoC's pipelines. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming See, we told you that Tapestry has never been and will never will be backwards compatible. That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are alternative ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the next best option (and I really use best in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that if you don't like not being able to subclass) of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of internal services (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the copied code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do this little tweak (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Law benny.mk@gmail.com wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Law benny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Res: Best way to extend a component?
If component classes were not meant to be subclassed, wouldn't it be nice to make them as final classes? It would not let people lose some time on it, since it would be seen at compilation time, and it's kinda logical. - Everton Agner Ramos De: Alex Kotchnev akoch...@gmail.com Para: Tapestry users users@tapestry.apache.org Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41 Assunto: Re: Best way to extend a component? I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming See, we told you that Tapestry has never been and will never will be backwards compatible. That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are alternative ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the next best option (and I really use best in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that if you don't like not being able to subclass) of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of internal services (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the copied code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do this little tweak (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Law benny.mk@gmail.com wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Law benny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate
Re: Res: Best way to extend a component?
very good roundup! Everton Agner wrote: If component classes were not meant to be subclassed, wouldn't it be nice to make them as final classes? It would not let people lose some time on it, since it would be seen at compilation time, and it's kinda logical. - Everton Agner Ramos De: Alex Kotchnevakoch...@gmail.com Para: Tapestry usersusers@tapestry.apache.org Enviadas: Quinta-feira, 13 de Maio de 2010 17:20:41 Assunto: Re: Best way to extend a component? I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming See, we told you that Tapestry has never been and will never will be backwards compatible. That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are alternative ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the next best option (and I really use best in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that if you don't like not being able to subclass) of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of internal services (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the copied code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do this little tweak (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Lawbenny.mk@gmail.com wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Lawbenny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula
Re: Best way to extend a component?
this was the good roundup! Andreas Alex Kotchnev wrote: I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming See, we told you that Tapestry has never been and will never will be backwards compatible. That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are alternative ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the next best option (and I really use best in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that if you don't like not being able to subclass) of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of internal services (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the copied code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do this little tweak (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Lawbenny.mk@gmail.com wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Lawbenny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Precisely. Thank you, Alex. Mixins are excellent for some things, but not a replacement for subclassing for every case. And you have to add a bit of extra code per usage in the .tml (t:mixin=...). On Thu, May 13, 2010 at 4:20 PM, Alex Kotchnev akoch...@gmail.com wrote: I think it is fair to say that T5 has indeed gone to great lengths to try to isolate the user from changes in the framework. Thus, if T5 decides to change the internal implementation of how a Select works, there wouldn't be 100 people screaming See, we told you that Tapestry has never been and will never will be backwards compatible. That is great and all, except that you run into the infamous T5 learning curve. Most developers that start with T5 already know a thing or two about Java, object orientation, and server side / web programming . Thus, if you give them some objects / classes, most people know how to extend a class and try to inject some custom behavior that way. There certainly are alternative ways of using the existing components (e.g. wrapping them in others, mixins, whatever) that in the general sense provide the needed extensibility. However, getting your head around those approaches (e.g. mixins), seems to require a big mountain of knowledge before being able to do some simple things that seem like they should be easily achievable through subclassing. So, the next best option (and I really use best in a very loose way, as in the least evil) is to go out and copy the source (I think I've seen a few recommendations on the list to do that if you don't like not being able to subclass) of the existing components ( which most people can understand), and make their tweaks in the user's copy of the component. Thus, if the framework moves on, it can technically say See, we did all of this in a backwards compatible way, everyone who was using our public API is still in a good shape . Now, the problem is that when the user copied the source from the T5 components, there is a pretty good chance that the copied source relies on a whole bunch of internal services (which give no guarantees of backward compatibility), and when the internal services move on, all the breakage will occur in the copied code. Thus, technically, although the public APIs did remain consistent and pristine, the end result is that by encouraging this approach the breakage becomes a lot bigger and seemingly harder to fix ('cause we all know that when you copy the source of a T5 component you might not understand ALL that's inside). Anyway, I don't really have a solution - both sides have valid points. Certainly, the framework authors should be able to evolve the framework as they see fit w/o having people screaming in their ear about backward compatibility. At the same point, the combination of not being able to subclass plus the plethora of new (and sometimes not easy to grasp) concepts makes it way too difficult when you just want to do this little tweak (even with the understanding that you're tying yourself to the implementation). T5 prides itself on how easy it is to create new components - create a class, a template, and boom - you can start using it just like any other component. Maybe there are things that can be done in limited ways to open up the most common components in ways that don't break their encapsulation (e.g. maybe events) but allow for easier extension. Back to the issue of documentation (which the wiki might help with), maybe as a community we can do a better job of explaining and giving examples of these new concepts . Anyway, my 2c. Regards, Alex K On Thu, May 13, 2010 at 3:43 PM, Benny Law benny.mk@gmail.com wrote: On Thu, May 13, 2010 at 3:29 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 13 May 2010 15:44:50 -0300, Benny Law benny.mk@gmail.com wrote: I want the user to consciously choose a value. select t:type=Select validate=required blankOption=always ... does the trick, no? No, because I don't want the blank option if there is only one valid option in the model, or if there is a valid initial value (if the bound property is not null to begin with and is one of the valid options). Again, this logic depends on the number of options available (as well as the current value), and I don't know the option list size if it is a dynamic list. I want this logic in the Select component across the board because it is generic and not specific to special cases. I don't want to incur extra code per usage. The simplest solution is just to override the spot in Select where it decides what to do when BlankOption is AUTO. It's a very simple case where inheritance + override would be very effective. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda.
Re: Best way to extend a component?
Thiago is right; it's more like a pipeline, although not exactly a pipeline, either. :) It's still a state machine, stepping through the various render phases, but in each render phase, you have a series of sub states, one for each mixin, + the component's own method. In 5.2, you can explicitly define the order of execution to make sure your mixin executes before any others, etc. (all of the commands supported by OrderedConfiguration are supported). And in 5.2, you can directly access a component's parameter from within the mixin, even if the component's parameter doesn't have a public getter. Robert On May 13, 2010, at 5/133:15 PM , Thiago H. de Paula Figueiredo wrote: On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnert a...@weberhofer.at wrote: this looks very promising!! that is what I was asking for and would solve at least my problem :) So with mixins you do/can not override a method, you build a execution chain instead? In a simplified view, mixins work like you had copied their methods to the component or page to which the mixin is applied. I wouldn't say it's an execution chain. This sounds more similar to Tapestry-IoC's pipelines. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
On Thu, 13 May 2010 17:56:22 -0300, Benny Law benny.mk@gmail.com wrote: Precisely. Thank you, Alex. Mixins are excellent for some things, but not a replacement for subclassing for every case. I agree. There's a very hard balance between opening and keeping backward compatibility. And you have to add a bit of extra code per usage in the .tml (t:mixin=...). I don't see as a problem at all, but it's my taste, of course. :) -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
Right. I'm simply pointing out a way to do that with mixins. For instance, we can add: @BindParamater; private SelectModel model; private BlankOption originalOption; and make beginRender* look something like this void beginRender() { originalOption = blankOption; if (blankOption == AUTO) { //we're changing this /just/ before the select gets rendered, overriding the user-defined value (or the default value) so that Tapestry's AUTO branch of the switch never gets invoked; we've now made the component //do the right thing. if (required model.getOptions.size() == 1) { blankOption=NEVER; } else { blankOption=ALWAYS; } } } void afterRender() { blankOption = originalOption; //this isn't strictly necessary, but it's a nicety. } * Note: I misnamed the method beforeRender in my earlier e-mail; should be beginRender. It's always bugged me that's it's beginRender and afterRender instead of beginRender and endRender or beforeRender and afterRender. :) Voila. Apply your mixin. auto behavior as desired, in a reusable format. Robert On May 13, 2010, at 5/131:44 PM , Benny Law wrote: As I explained before, I want to change the auto behavior to make it smarter. Currently, there is really no intelligence in the logic: a blank option is added if the field is not required, and no blank option is added if the field is required. When the option list is static, I can set the blank option myself, no problem. But when the list is dynamic, I don't know ahead of time how many options there will be, so I want the Select component to decide for me. If the field is required, I still want a blank option unless there is exactly one option because I don't want the first option to be selected as a default. I want the user to consciously choose a value. On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler robe...@scazdl.org wrote: Why are you wanting to change the auto behavior in the first place? In the few cases where there is no sensible default value, is using the blankLabel and blankOption parameters so excruciatingly onerous? If so, why not not simply wrap the select component in a custom select component that provides the values you want? You would have to provide parameters in your wrapper that passed through to the underlying select, but this is certainly doable. In fact, this particular case could be handled (I think?) in 5.2 in a very clean way. 5.2 introduces the possibility for mixins to bind and manipulate the containing component's parameters. So you could, in theory, write a mixin that sets the appropriate values for you. Basically, you would have something like this: public class Blank { @BindParameter private boolean required; @BindParameter private BlankOption blankOption; @BindParameter private blankLabel blankLabel; void beginRender() {//this will happen before the select's before render... if (//whatever condition you want) { blankOption=ALWAYS;//we've now overridden the default check in showBlankOption() b/c by the time that renders, showBlankOption will see blankOption as being ALWAYS instead of AUTO. blankLabel=Select one...; } else { blankOption=NEVER; } } } Which you could then use like: t:select ... t:mixins=blank/ which seems very non-onerous to me. :) Robert On May 13, 2010, at 5/1312:56 PM , Benny Law wrote: I did look at the demo Geoff posted. How is that going to provide what I need? I'm sorry, but I fail to see this easy fix you mentioned. Maybe you can be a bit more specific? On Thu, May 13, 2010 at 1:15 PM, Christian Riedel cr.ml...@googlemail.comwrote: Well I agree that some more extensibility could be made here and there. That particular problem looks like it's worth a JIRA with a patch from you that makes the component extensible to fix that problem :) On the other hand there is an easy fix. Just look at the demo Geoff posted. Why do you insist on the BlankOption thing? Just add your blank option directly to the list select-options. Then there is no blank option at all... Am 13.05.2010 um 16:43 schrieb Benny Law: Thanks Geoff, but no, it doesn't. Your example shows how the Select component works as is. What I need is a smarter interpretation of BlankOption.AUTO. Basically, if you look at the showBlankOption() method in the Select class, you see this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; default: return !isRequired(); } What I want is this: switch (blankOption) { case ALWAYS: return true; case NEVER: return false; // AUTO: Decide based on model size, current value, and required or not. default: ListOptionModel options = model.getOptions(); if (options.size() == 1) {
Re: Best way to extend a component?
so, I just hope 5.2 is around the corner ... Robert Zeigler wrote: Thiago is right; it's more like a pipeline, although not exactly a pipeline, either. :) It's still a state machine, stepping through the various render phases, but in each render phase, you have a series of sub states, one for each mixin, + the component's own method. In 5.2, you can explicitly define the order of execution to make sure your mixin executes before any others, etc. (all of the commands supported by OrderedConfiguration are supported). And in 5.2, you can directly access a component's parameter from within the mixin, even if the component's parameter doesn't have a public getter. Robert On May 13, 2010, at 5/133:15 PM , Thiago H. de Paula Figueiredo wrote: On Thu, 13 May 2010 17:09:45 -0300, Andreas Bohnerta...@weberhofer.at wrote: this looks very promising!! that is what I was asking for and would solve at least my problem :) So with mixins you do/can not override a method, you build a execution chain instead? In a simplified view, mixins work like you had copied their methods to the component or page to which the mixin is applied. I wouldn't say it's an execution chain. This sounds more similar to Tapestry-IoC's pipelines. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Best way to extend a component?
- a bit off topic I know but... I like beforeRender() and afterRender() for it's clear when they occur and why. Whereas beginRender() and endRender() sound like instructions - but onBeginRender() and onEndRender() on the other hand are also very clear, if not more so... Hmm... On 13 May 2010 17:12, Robert Zeigler robe...@scazdl.org wrote: * Note: I misnamed the method beforeRender in my earlier e-mail; should be beginRender. It's always bugged me that's it's beginRender and afterRender instead of beginRender and endRender or beforeRender and afterRender. :) - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Confirm mixin won't cancel when in zone
I have a Confirm mixin that works fine until I put it in a zone. It still pops up a confirmation dialog but when Cancel is pressed the mixin fails to stop the event. My mixin adds javascript that observes the element, but the zone seems to upset it by adding javascript directly to the element, eg: a id=eventlink onclick=javascript:Tapestry.waitForPage(event); shape=rect href=./simplewithzone:deleteDelete.../a What do I need to change in Confirm to make it stop the event when there's a zone? Here's source for confirm.js and Confirm.java: var Confirm = Class.create(); Confirm.prototype = { initialize: function(elementId, message) { this.message = message; Event.observe($(elementId), 'click', this.doConfirm.bindAsEventListener(this)); }, doConfirm: function(e) { if (! confirm(this.message)) { e.stop(); } } } package jumpstart.web.mixins; import org.apache.tapestry5.BindingConstants; import org.apache.tapestry5.ClientElement; import org.apache.tapestry5.RenderSupport; import org.apache.tapestry5.annotations.AfterRender; import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; import org.apache.tapestry5.annotations.InjectContainer; import org.apache.tapestry5.annotations.Parameter; import org.apache.tapestry5.ioc.annotations.Inject; @IncludeJavaScriptLibrary(confirm.js) public class Confirm { @Parameter(value = Are you sure?, defaultPrefix = BindingConstants.LITERAL) private String message; @Inject private RenderSupport renderSupport; @InjectContainer private ClientElement element; @AfterRender public void afterRender() { renderSupport.addScript(String.format(new Confirm('%s', '%s');, element.getClientId(), message)); } } Thanks in advance, Geoff
Re: Confirm mixin won't cancel when in zone
On Thu, 13 May 2010 21:22:25 -0300, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: a id=eventlink onclick=javascript:Tapestry.waitForPage(event); shape=rect href=./simplewithzone:deleteDelete.../a I'm no JavaScript guru (very far from that, actually), but have you tried setting onclick to null? -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Confirm mixin won't cancel when in zone
just as an aside, you don't need to prefix your onclick with 'javascript:' Geoff Callender wrote: a id=eventlink onclick=javascript:Tapestry.waitForPage(event); shape=rect href=./simplewithzone:deleteDelete.../a - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Confirm mixin won't cancel when in zone
I'm not doing that - Tapestry is when it adds zone support. On 14/05/2010, at 10:54 AM, Paul Stanton wrote: just as an aside, you don't need to prefix your onclick with 'javascript:' Geoff Callender wrote: a id=eventlink onclick=javascript:Tapestry.waitForPage(event); shape=rect href=./simplewithzone:deleteDelete.../a - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Tutorial: Chapter 4: Forms in Tapestry
Can someone please post a copy of of all the .java .tml .properties files for this chapter in the tutorial. The first tutorial was riddled with outdated elements and bugs that caused much pain. I've now hit another road block with this chapter and am hoping to head things off earlier this time round. Last night, I posted a full set of working source for the first 3 chapters of the tutorial. Many thanks, Phil -- View this message in context: http://old.nabble.com/Tutorial%3A-Chapter-4%3A-Forms-in-Tapestry-tp28554618p28554618.html Sent from the Tapestry - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Hi Lo tutorial, HIbernate cfg errors
Can you post working code (.tml and .java) for chapter 4 of the tutorial on working with forms? I'm having trouble getting it to work and there is nowhere a listing of full source - only snippets and pieces. The first 3 chapters had critical errors in some of the snippets and caused me major grief trying to learn from the flaky tutorial code. Thanks! Phil tfecw wrote: Im' trying to get through the Hi Lo game and I'm having a lot more difficulties than I should be having (i tried tomcat 5 for a day before moving over to jetty) I'm at the part of the tutorial where you guess the number by clicking on links. for some reason this line of code: t:loop source=1..10 value=guess xml:space=preserve t:actionlink t:id=link context=guess${guess}/t:actionlink /t:loop Is throwing a hibernate related error (see below) when i remove the context=guess part from the code i don't get the hibernate error anymore but I do get some a tapestry related error regarding actions. Here is the hibernate error i get: Render queue error in BeginRender[Guess:link]: Exception constructing service 'ValueEncoderSource': Error invoking service builder method org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map) (at TapestryModule.java:1745) (for service 'ValueEncoderSource'): Error invoking service contribution method org.apache.tapestry5.hibernate.HibernateModule.contributeValueEncoderSource(MappedConfiguration, boolean, HibernateSessionSource, Session, TypeCoercer, PropertyAccess, LoggerSource): Exception constructing service 'HibernateSessionSource': Error invoking service builder method org.apache.tapestry5.hibernate.HibernateModule.buildHibernateSessionSource(Logger, List, RegistryShutdownHub) (at HibernateModule.java:120) (for service 'HibernateSessionSource'): /hibernate.cfg.xml not found Let me know if the full stack trace is needed. -- View this message in context: http://old.nabble.com/Hi-Lo-tutorial%2C-HIbernate-cfg-errors-tp22230480p28554683.html Sent from the Tapestry - User mailing list archive at Nabble.com. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
autocomplete mixin - move the box closer to the input field
i've just started using the autocomplete mixin after reading this demo: http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/autocompletemixin one thing i'd like to change is how far away the search result div appears from the input text. i'd like to reduce the gap to 0 pixels if at all possible.. any tips? thanks, p. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: autocomplete mixin - move the box closer to the input field
just further to that, i'm new to tapestry5 and haven't completed my reading on ajax etc, but how would i listen for the 'something selected from list' event (for the autocomplete mixin), and do some asynchronous server side processing? advice or direction to docs/articles appreciated! thanks, p. Paul Stanton wrote: i've just started using the autocomplete mixin after reading this demo: http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/autocompletemixin one thing i'd like to change is how far away the search result div appears from the input text. i'd like to reduce the gap to 0 pixels if at all possible.. any tips? thanks, p. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: autocomplete mixin - move the box closer to the input field
On Fri, 14 May 2010 00:24:12 -0300, Paul Stanton p...@mapshed.com.au wrote: i've just started using the autocomplete mixin after reading this demo: http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/autocompletemixin one thing i'd like to change is how far away the search result div appears from the input text. i'd like to reduce the gap to 0 pixels if at all possible.. Just use ordinary CSS style override. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: autocomplete mixin - move the box closer to the input field
On Fri, 14 May 2010 00:43:02 -0300, Paul Stanton p...@mapshed.com.au wrote: just further to that, i'm new to tapestry5 and haven't completed my reading on ajax etc, but how would i listen for the 'something selected from list' event (for the autocomplete mixin), and do some asynchronous server side processing? From the Autocomplete page: http://tapestry.apache.org/tapestry5.1/tapestry-core/ref/org/apache/tapestry5/corelib/mixins/Autocomplete.html Just create a method ListString onProvideCompletionsFrom[component id](String string) { // return a list of string containing the suggestions. } I'm not sure I understood what you meant, but Tapestry handles all the AJAX plumbing for you automatically. Just handle the event triggered by the component, mixin or page. Writing a method to handle an AJAX request triggered by a Tapestry component, mixin or page event is done exactly in the same way non-AJAX events are handled. Each component and mixin defines which events they triggers and how they process the value returned by the event handler method. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: autocomplete mixin - move the box closer to the input field
Ol' Firebug tells me the autocomplete div looks like this: div id=countryName:menu class=t-autocomplete-menu style=position: absolute; left: 152px; top: 126px; width: 146px; display: none; So I guess you should be looking to CSS style-ise #countryName:menu or .t-autocomplete-menu Steve. On 13 May 2010 23:48, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Fri, 14 May 2010 00:24:12 -0300, Paul Stanton p...@mapshed.com.au wrote: i've just started using the autocomplete mixin after reading this demo: http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/autocompletemixin one thing i'd like to change is how far away the search result div appears from the input text. i'd like to reduce the gap to 0 pixels if at all possible.. Just use ordinary CSS style override. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org