Re: How to fix the id attribute of a select component
I understand that Tapestry is doing this to avoid potential conflicts, but can somebody provide a real example of when this is necessary? This behavior seems to be causing confusion and inconvenience to people, myself included. Even when the danger of the conflict is real, there are still cases when it is not, so perphaps making this behavior an option and allowing the developer control over it will make life easier for some. Benny On Tue, Feb 8, 2011 at 9:28 AM, Richard Hill r...@su3analytics.com wrote: Hi Mark, Yes that is correct, it is being clobbered by tapestry (5.2) - specifically tapestry is appending a character sequence like myIdName_672hjfty6. I have also tried Igor's suggestion of clientId and various permutations, but no luck I'm afraid. R. On Mon, 2011-02-07 at 11:40 -0600, Mark wrote: So when you use: t:select t:type=select t:id=cctEditSelect t:blankOption=NEVER onchange=_SU3.renderWebOptions(); id=myIdName/ myIdName is being overwritten by something else? Mark On Mon, Feb 7, 2011 at 5:23 AM, Richard Hill r...@su3analytics.com wrote: Hi Igor, Thanks for the response. I forget to mention in my original email that I tried setting the id attribute as well, but to no avail - it gets over-written. This is T5.2. Richard. On Mon, 2011-02-07 at 12:20 +0100, Igor Drobiazko wrote: t:id is a Tapestry component id, which has nothing to do with the client-side id of the tag written by the component. You should use the clientId parameter. On Mon, Feb 7, 2011 at 10:30 AM, Richard Hill r...@su3analytics.com wrote: Hi All, I have a select component in a block: t:select t:type=select t:id=cctEditSelect t:blankOption=NEVER onchange=_SU3.renderWebOptions();/ The block is the second of three. The switching between them is accomplished with an ajax actionlink request and a t:delegate to / By default the first block is shown on page load. If I then switch to the second block, the id attribute of the t:select is something like: id=cctEditSelect_947gyh0 My onchange javascript function expects this to be simply cctEditSelect. If I refresh the whole page, then the id _is_ rendered just cctEditSelect (the currently visible block is @Persist'd). It's only when switching from another block do I get the random characters appended. I'm guessing this is to do with Tapestry making sure there are no id conflicts. I have tried to force the id, by putting in my .java: @InjectComponent @Id(cctEditSelect) private Select cctEditSelect; But no juice - I get the same behaviour. How can I fix this id attribute? Many thanks, Richard. -- Best regards, Igor Drobiazko http://tapestry5.de - 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: How to fix the id attribute of a select component
Yes, but in this case, I don't see any potential for conflicts. After the zone update, you will still have one select element, but with a new id. This seems to have tripped up people who are new to Tapestry. My question is, does it not make sense to perhaps add a parameter to the zone component so that the developer can basically say, I know what I am doing, and I don't want the ids to be updated please, something like t:zone ... updateIds=false ...? I know we can work around this by using CSS classes instead of ids to reference the elements, but it's just not the natural thing to do. Benny On Tue, Feb 8, 2011 at 10:36 AM, Richard Hill r...@su3analytics.com wrote: Sure. But in my case I have only the one element, it's static in .tml and not rendered in a loop. I think maybe what's causing it is that the element (t:select) is contained within the zone it updates. On Tue, 2011-02-08 at 12:56 -0200, Thiago H. de Paula Figueiredo wrote: On Tue, 08 Feb 2011 12:50:57 -0200, Benny Law benny.mk@gmail.com wrote: I understand that Tapestry is doing this to avoid potential conflicts, but can somebody provide a real example of when this is necessary? Anytime you could have the same id used twice in a page, something that is forbidden by HTML and causes lots of confusion in JavaScript and CSS. This can happen in at least two situations: loops and AJAX updates. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5: Recording errors for fields in a loop
Hi Stephan, Thanks for providing this solution. I tried to implement this, but got stuck on the last step. Could you tell me how you set the saved controlName to the component? I couldn't find a public setter for this property. I searched the whole class hierarchy for TextField and couldn't find anything. Do I need to create a wrapper for it? Thanks. Benny On Fri, Feb 4, 2011 at 4:30 AM, Stephan Windmüller stephan.windmuel...@tu-dortmund.de wrote: On 02.02.2011 16:39, Benny Law wrote: Yes, I am doing cross-field validation (e.g. quantity is required if another property of the item has a certain value) and that's why it has to be done in onValidateForm(), or at least that's what I think. We have a similar issue in our application. You can solve yours like this: - Inject the textfield in your page - In onValidateFromQuantatiy(String), store quantity.getControlName in a Map - In onValidateForm, proceed with your validation. To record an error, set the saved controlName to the component and push it into recordError HTH Stephan - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5: Recording errors for fields in a loop
Thanks Stephan, I got it working now. I wonder if built-in support for this has been requested as an enhancement? Benny On Fri, Feb 4, 2011 at 12:59 PM, Stephan Windmüller stephan.windmuel...@tu-dortmund.de wrote: On 04.02.2011 17:44, Benny Law wrote: Thanks for providing this solution. I tried to implement this, but got stuck on the last step. Could you tell me how you set the saved controlName to the component? I couldn't find a public setter for this property. I searched the whole class hierarchy for TextField and couldn't find anything. Do I need to create a wrapper for it? Thanks. Sorry, I forgot. You need to implement a simple field (implementing Field) which passes the methods public void setControlName(String controlName); public String getControlName(); to the public. Insert it in your tml and inject it in your java class, acting as a dummy for the validation. HTH Stephan - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5: Recording errors for fields in a loop
The following code illustrates what I am doing: t:form t:id=form ... t:loop source=items value=item ... t:textfield t:id=quantity value=item.quantity .../ /t:loop /t:form @InjectComponent private Form form; @InjectComponent private TextField quantity; @Property private Item item; void onValidateForm() { for (Item i: getItems()) { if (...cross-field check...) { form.recordError( quantity, Error message); } } } What I find is that when I get to onValidateForm(), the injected quantity field is always the last instance (the one bound to the last item). I need a way to get the instance that matches the current item in the for loop. Hope that clarifies my question. Thanks. Benny On Wed, Feb 2, 2011 at 6:21 AM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Wed, 02 Feb 2011 02:26:45 -0200, Benny Law benny.mk@gmail.com wrote: Hi, Hi! I have a loop inside a form that renders a textfield and some other controls. When I am doing cross field validations in the ValidateForm event while iterating over a collection (the source of the loop), I would like to record error messages against the form with the field in error to get the normal error highlighting. How can I get to the field in this case since I can't use normal injection? Why not? Even when inside a loop, you don't have more than one instance of a given component. Example: t:loop ... t:textfield t:id=title.../ /t:loop You have only one instance of the TextField with t:id title, regardless of the number of iterations. I don't know if this solves your problem, but at least I'm trying to help you figure it out. ;) -- 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: T5: Recording errors for fields in a loop
Yes, I am doing cross-field validation (e.g. quantity is required if another property of the item has a certain value) and that's why it has to be done in onValidateForm(), or at least that's what I think. Benny On Wed, Feb 2, 2011 at 10:32 AM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Why don't you use onPrepareFromQuantity(Integer quantity) instead? Does this validation require other fields to be checked? On Wed, 02 Feb 2011 12:49:58 -0200, Benny Law benny.mk@gmail.com wrote: The following code illustrates what I am doing: t:form t:id=form ... t:loop source=items value=item ... t:textfield t:id=quantity value=item.quantity .../ /t:loop /t:form @InjectComponent private Form form; @InjectComponent private TextField quantity; @Property private Item item; void onValidateForm() { for (Item i: getItems()) { if (...cross-field check...) { form.recordError( quantity, Error message); } } } What I find is that when I get to onValidateForm(), the injected quantity field is always the last instance (the one bound to the last item). I need a way to get the instance that matches the current item in the for loop. Hope that clarifies my question. Thanks. Benny On Wed, Feb 2, 2011 at 6:21 AM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Wed, 02 Feb 2011 02:26:45 -0200, Benny Law benny.mk@gmail.com wrote: Hi, Hi! I have a loop inside a form that renders a textfield and some other controls. When I am doing cross field validations in the ValidateForm event while iterating over a collection (the source of the loop), I would like to record error messages against the form with the field in error to get the normal error highlighting. How can I get to the field in this case since I can't use normal injection? Why not? Even when inside a loop, you don't have more than one instance of a given component. Example: t:loop ... t:textfield t:id=title.../ /t:loop You have only one instance of the TextField with t:id title, regardless of the number of iterations. I don't know if this solves your problem, but at least I'm trying to help you figure it out. ;) -- 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 -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, Ars Machina Tecnologia da Informação Ltda. Consultor, desenvolvedor e instrutor em Java, Tapestry e Hibernate Coordenador e professor da Especialização em Engenharia de Software com Ênfase em Java da Faculdade Pitágoras http://www.arsmachina.com.br - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
T5: Recording errors for fields in a loop
Hi, I have a loop inside a form that renders a textfield and some other controls. When I am doing cross field validations in the ValidateForm event while iterating over a collection (the source of the loop), I would like to record error messages against the form with the field in error to get the normal error highlighting. How can I get to the field in this case since I can't use normal injection? Thanks in advance, Benny
Re: Suspending and restoring a form in T5
Thanks Norman for your ideas. I will explore them and see what makes the most sense in my case. I was hoping that there would be something in Tapestry that I could utilize to make it easier, but I guess not. Regards, Benny On Mon, Jan 17, 2011 at 4:27 PM, Norman Franke nor...@myasd.com wrote: You could use JavaScript to hide the form and use AJAX to put something else there. Or create a new absolutely positioned DIV that covers the entire contents of the form and use AJAX to do whatever. A sort of easy way is to put all your content in a single DIV and just hide that and have another DIV that you can then show, with optional AJAX update. Along these lines, I've used the ModalBox dialog library to display a dialog where the user can lookup stuff and hide it when they select whatever they want. When they click on the desired item, I auto fill that into the desired field on the original form. Otherwise, I'd serialize the form values into a large hidden text field in a separate, but hidden form, and submit that. Store that in the session. Then restore later. Google for a prototype-compatible Form deserialization routing, I recall needing one a while go and found one. Norman Franke Answering Service for Directors, Inc. www.myasd.com On Jan 15, 2011, at 1:14 PM, Benny Law wrote: I am developing a mobile application with Tapestry 5. Sometimes, when entering data on a form, I need to display another page (some kind of look-up) where the user can eventually select some value that needs to be brought back to the original form. For desktop web applications, I could implement the look-up page with an iframe so that the user doesn't need to leave the original form. Now, with the mobile application where I can't use iframe, I need some way to suspend the form, saving the state of the form as is without validating anything. Upon returning from the look-up page, I need to restore the form to the state it was in when the user opened the look-up page. What is the best way to do this in Tapestry? Benny
Re: Suspending and restoring a form in T5
Thanks Norman for your ideas. I will explore them and see what makes the most sense in my case. I was hoping that there would be something in Tapestry that I could utilize to make it easier, but I guess not. Regards, Benny On Mon, Jan 17, 2011 at 4:27 PM, Norman Franke nor...@myasd.com wrote: You could use JavaScript to hide the form and use AJAX to put something else there. Or create a new absolutely positioned DIV that covers the entire contents of the form and use AJAX to do whatever. A sort of easy way is to put all your content in a single DIV and just hide that and have another DIV that you can then show, with optional AJAX update. Along these lines, I've used the ModalBox dialog library to display a dialog where the user can lookup stuff and hide it when they select whatever they want. When they click on the desired item, I auto fill that into the desired field on the original form. Otherwise, I'd serialize the form values into a large hidden text field in a separate, but hidden form, and submit that. Store that in the session. Then restore later. Google for a prototype-compatible Form deserialization routing, I recall needing one a while go and found one. Norman Franke Answering Service for Directors, Inc. www.myasd.com On Jan 15, 2011, at 1:14 PM, Benny Law wrote: I am developing a mobile application with Tapestry 5. Sometimes, when entering data on a form, I need to display another page (some kind of look-up) where the user can eventually select some value that needs to be brought back to the original form. For desktop web applications, I could implement the look-up page with an iframe so that the user doesn't need to leave the original form. Now, with the mobile application where I can't use iframe, I need some way to suspend the form, saving the state of the form as is without validating anything. Upon returning from the look-up page, I need to restore the form to the state it was in when the user opened the look-up page. What is the best way to do this in Tapestry? Benny
Suspending and restoring a form in T5
I am developing a mobile application with Tapestry 5. Sometimes, when entering data on a form, I need to display another page (some kind of look-up) where the user can eventually select some value that needs to be brought back to the original form. For desktop web applications, I could implement the look-up page with an iframe so that the user doesn't need to leave the original form. Now, with the mobile application where I can't use iframe, I need some way to suspend the form, saving the state of the form as is without validating anything. Upon returning from the look-up page, I need to restore the form to the state it was in when the user opened the look-up page. What is the best way to do this in Tapestry? Benny
Tapestry 5.1.0.5 and HTML 5 Doctype
Thanks everyone for your help. The patch for https://issues.apache.org/jira/browse/TAP5-1040 is the best solution for me for now. Warm regards, Benny
Re: Tapestry 5.1.0.5 and HTML 5 Doctype
I have looked at the patch provided in https://issues.apache.org/jira/browse/TAP5-840 but it seems to be dealing with the issue of entities only and it's not for Tapestry 5.1.0.5. What I really want is to be able to output !DOCTYPE html. Putting this in the .tml file isn't working. Can somebody suggest a solution for this please? Benny On Wed, Jan 12, 2011 at 9:47 AM, Benny Law benny.mk@gmail.com wrote: Hi François, Thanks for the info. I am aware of TAPS-840 but haven't studied the patch. It looks like that's the only solution for now. Without !DOCTYPE html, Firefox 3.6 renders the page in Quirks mode instead of Standards compliance mode, and I have already noticed some minor issues. I hope this patch gets integrated with Tapestry soon. Benny 2011/1/12 François Facon francois.fa...@atosorigin.com Hi Benny, In order to use html5 in our Web Mobile Solution, I have ask Robin to work on html5 compatibility last year. He had post our feedback in the mailing list. The thread is here http://tapestry.1045711.n5.nabble.com/State-on-HTML5-integration-woodstox-rollback-td2470926.html I suggest you also to have a look on the related Jira https://issues.apache.org/jira/browse/TAP5-840 If you don't want to patch Tapestry, you have to know that currently most of modern browser run html5 tag even if you are not using !DOCTYPE html. For client side detection Modernizr http://www.modernizr.com/%20is very fine. 2011/1/12 Benny Law benny.mk@gmail.com I am trying to convert my pages to HTML5 but am having problem getting the correct DOCTYPE to be output. The !DOCTYPE html I put in the .tml file is ignored, and the generated HTML code has no DOCTYPE. I'm interested in how people are working around this. Thanks. Benny
Re: Tapestry 5.1.0.5 and HTML 5 Doctype
Hi François, Thanks for the info. I am aware of TAPS-840 but haven't studied the patch. It looks like that's the only solution for now. Without !DOCTYPE html, Firefox 3.6 renders the page in Quirks mode instead of Standards compliance mode, and I have already noticed some minor issues. I hope this patch gets integrated with Tapestry soon. Benny 2011/1/12 François Facon francois.fa...@atosorigin.com Hi Benny, In order to use html5 in our Web Mobile Solution, I have ask Robin to work on html5 compatibility last year. He had post our feedback in the mailing list. The thread is here http://tapestry.1045711.n5.nabble.com/State-on-HTML5-integration-woodstox-rollback-td2470926.html I suggest you also to have a look on the related Jira https://issues.apache.org/jira/browse/TAP5-840 If you don't want to patch Tapestry, you have to know that currently most of modern browser run html5 tag even if you are not using !DOCTYPE html. For client side detection Modernizr http://www.modernizr.com/%20is very fine. 2011/1/12 Benny Law benny.mk@gmail.com I am trying to convert my pages to HTML5 but am having problem getting the correct DOCTYPE to be output. The !DOCTYPE html I put in the .tml file is ignored, and the generated HTML code has no DOCTYPE. I'm interested in how people are working around this. Thanks. Benny
Tapestry 5.1.0.5 and HTML 5 Doctype
I am trying to convert my pages to HTML5 but am having problem getting the correct DOCTYPE to be output. The !DOCTYPE html I put in the .tml file is ignored, and the generated HTML code has no DOCTYPE. I'm interested in how people are working around this. Thanks. Benny
Re: datefield - no option to cancel?
The DateField has always been on my list of things that require fixes/enhancements/workarounds for some minor flaws, but I never got to it because of other higher priority issues I had to deal with. I was always annoyed by the fact that I couldn't cancel the popup just by clicking outside like I can with other dropdowns/popups. I would think that it could be fixed fairly easily by people who know the code behind the component. However, I am beginning to lose heart when most people seem to have simply given up on this component that is part of Tapestry. Is it really dead, or should I keep believing that DateField is still alive and will continue to be improved upon? Benny On Sun, Jan 9, 2011 at 3:34 PM, Bryan Lewis jbryanle...@gmail.com wrote: I switched our apps some time ago to Tapx Datefield and we've been happy with it. The only annoyance about it was the inability to easily override the date parser. I was asked to make it accept two-digit years and I had to hack the source. But we were totally happy with it before that requirement! On Sun, Jan 9, 2011 at 3:17 PM, Paul Stanton p...@mapshed.com.au wrote: yeah unfortunately, i'm going to have to give up on it too. have logged jira issues. jQuery isn't the best fit for me though, since prototype/scriptaculous is already required and i don't want to have another javascript framework dependency. what other date components are there out there that people have used? On 9/01/2011 8:54 PM, Gunnar Eketrapp wrote: I gave up on datefield and switched to jQuery datepicker ... 2011/1/9 Paul Stantonp...@mapshed.com.au: further to this, say your date format is m/d/ and the initial value is 1/1/2011 and you want to change it to 2/1/2011.. that is not possible. changing month, the selected 'day' is still selected and therefore not selectable. use case: initial date is 2/1/2011 1. open date picker 2. change month to feb 3. try to click on 1st of feb - nothing happens. On 9/01/2011 9:50 AM, Paul Stanton wrote: hi all, using the datefield component, if a user changes their mind there seems to be no way for them to close the popup without changing the value in some way http://tapestry.apache.org/tapestry5.2-dev/tapestry-core/ref/org/apache/tapestry5/corelib/components/DateField.html once the icon has been clicked, there's no option to close the popup explicitly and selecting the current value is disabled so the user has to select another date to close the popup. am i missing something or should i log an issue? 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 - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: datefield - no option to cancel?
Just added a comment to TAP5-1408. Thanks. Benny On Sun, Jan 9, 2011 at 4:06 PM, Paul Stanton p...@mapshed.com.au wrote: there is now (as of about 2 hrs ago) https://issues.apache.org/jira/browse/TAP5-1408 https://issues.apache.org/jira/browse/TAP5-1409 i'd prefer to use a built in tapestry component over another JS solution or tapestry extension but as it stands the component is not suitable. i may try and patch it interesting that tapx has a better datefield and is howards baby ... why isn't this included in tapestry? licensing issues? p. On 10/01/2011 8:00 AM, Thiago H. de Paula Figueiredo wrote: On Sun, 09 Jan 2011 18:58:47 -0200, Benny Law benny.mk@gmail.com wrote: However, I am beginning to lose heart when most people seem to have simply given up on this component that is part of Tapestry. Is it really dead, or should I keep believing that DateField is still alive and will continue to be improved upon? Is there a JIRA about it? - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: translators in 5.2, and re-use as formatters
Hi Paul, I share your view on this topic. Some time ago, I was struggling a bit with trying to control the precise formatting of numeric fields, and I eventually had to create a new translator with a new binding. The toClient() method of the translator takes care of the required formatting specified by the binding expression. I wasn't totally happy with the solution, but it has been working for me and I don't have time to look for alternatives. If you come up with a good solution, please share it. Thanks. Benny On Thu, Dec 23, 2010 at 11:19 PM, Paul Stanton p...@mapshed.com.au wrote: Thanks Bryan, Yes it seems this is some functionality that has been victim of some other architectural concept. This is confusing and disappointing to me - I see it as a key facility that should be provided by the framework since one of the key tasks (you could argue the key task) of web applications is to convert objects into strings and back again. I see the role of formatters and translators intricately linked - otherwise there is certain code repetition and therefore maintenance issues. Also, constantly defining getter methods in components to make global formatters available is hardly a good approach, and no better than extending a 'BaseComponent' to access these properties. This could be solved with the old style service binding prefix which is also gone from the implementation. If no one can tell me what existing tapestry concept I'm missing I may spend some time seeing if I can write some code to get this going. Step one would be to create an object structure that makes it easy to define an object that implements both Translator and Formatter. Step two would be to create a binding prefix to supply the appropriate Translator/Formatter object to components, which would be registered in the binding prefix by name. p.
Re: Discussion
I am using Tapestry on a project that manages humanitarian aid delivery, and I think it's serious enough. Not only is Tapestry used for serious projects, it's also for serious developers. Tapestry does come with a steep learning curve, and it requires you to unlearn many old ways of doing things. If you are serious and committed, you will be rewarded greatly in the end. Benny On Tue, Dec 21, 2010 at 9:58 AM, Michael Gentry mgen...@masslight.netwrote: Is Tapestry really used for serious projects? Without trying to sound too aloof or flippant, the answer is: Yes. Not all of us can advertise the projects we work on, but T5 is definitely used for serious projects. mrg - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Prevent double submission w/linkSubmit
Instead of trying to disable every element that can trigger a form submission, I stop the form submission event itself. Here is the JavaScript I have been using, and it seems to be working for me: document.observe(dom:loaded, function() { $$(form).invoke(observe, submit, function(event) { if (this.submitted) { event.stop(); } else { this.submitted = true; }; }); }); Benny On Fri, Dec 10, 2010 at 2:43 PM, David Rees dree...@gmail.com wrote: On Thu, Dec 9, 2010 at 2:57 PM, Benny Law benny.mk@gmail.com wrote: Keep in mind that a form could be submitted by pressing the Enter key inside a text field. A safer approach would be to prevent the form itself from being submitted more than once, regardless of how it is submitted. Right - and as I stated in my original post I tried disabling the link by observing the FORM_PREPARE_FOR_SUBMIT_EVENT event - but for some reason you can't disable the link like you can a button... I also tried using a Javascript variable to see if the form had been submitted once already or not, but I was not able to get the event to stop... -Dave - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Prevent double submission w/linkSubmit
Keep in mind that a form could be submitted by pressing the Enter key inside a text field. A safer approach would be to prevent the form itself from being submitted more than once, regardless of how it is submitted. Benny 2010/12/9 françois facon fra.fa...@gmail.com Hi David about stopping the event. did you try to implement a mixin like clickonce? http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/creatingmixins1 François 2010/12/4 David Rees dree...@gmail.com I'm having problems figuring out how to prevent double clicks with a linkSubmit. With a regular submit, you can just disable the submit button after observing a FORM_PREPARE_FOR_SUBMIT_EVENT, but this doesn't seem to work for a linkSubmit element. Using T5.1.0.8-SNAPSHOT. Any ideas? Have also tried stopping the event but that doesn't seem to do anything. -Dave - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Using readonly textarea inside a Form component
Or, if you really want the textarea to be readonly (vs disabled), just add the readonly=readonly attribute. This allows the user to set focus to it and copy content from it but not change the content, and it doesn't get the disabled appearance. Benny On Mon, Jul 12, 2010 at 8:46 AM, Christophe Cordenier christophe.corden...@gmail.com wrote: Hi AFAIR Tapestry simply append 'disabled' in the generated markup. Using CSS to stylize .disabled should to the trick. 2010/7/12 Stephan Windmüller stephan.windmuel...@cs.tu-dortmund.de Hello! I am trying to use a read-only textarea component inside a form component. When the form is submitted, I get this error: org.apache.tapestry5.runtime.ComponentEventException: Failure writing parameter 'value' of component xxx.textarea: Binding org.apache.tapestry5.internal.services.attributeexpansionbind...@ce988a is read-only. Is it possbible to mark the component itself as read-only? Setting t:disabled=true works but the textarea is rendered differently. Regards Stephan - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Regards, Christophe Cordenier. Committer on Apache Tapestry 5 Co-creator of wooki @wookicentral.com
Re: event handlers - handling by the container (page)
Try giving your MyLayout component an id in MyPage.tml and use that id in the event handler name. You can't reference the id of the form component because it's not a direct child of the page. When an event bubbles up, it will appear to be coming from the immediate child. I think you can even omit the id and just have Object onSuccess(), provided there isn't any other form on the page. Benny On Tue, Jun 8, 2010 at 7:57 AM, Paul Stanton p...@mapshed.com.au wrote: Note that events that are not handled by a component will bubble up to the component's container I'm a little confused because I thought this meant I could have a component containing components and handle the events from the root container aka the page ? eg MyLayout.tml ... t:form t:id=myForm t:body / t:submit t:id=mySubmit / /t:form ... MyPage.tml html t:type=mylayout ... psome content/p /html MyPage.java ... Object onSuccessFromMyForm() { LOG.debug(onSuccessFromMyForm); } ... Should this listener get called or should I get : Request event 'success' (on component MyPage:myForm.success) was not handled; you must provide a matching event handler method in the component or in one of its containers. ? - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Contribute server startup ?
Hi Nicolas, Take a look at this: http://tapestry.apache.org/tapestry5.1/tapestry-ioc/startup.html Benny On Mon, May 31, 2010 at 10:50 AM, Nicolas Gillet - MARKET-IP nicolas.gil...@market-ip.com wrote: Hello, I am looking for a way to execute a piece of code only once at server startup. I want this in order to check if my database is empty (and then at the mandatory default records). So the context must be already initialized in order to user my manager/dao. Is this possible on T 5.1 ? and obviously how ? Thank you =) Nicolas Gillet
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?
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?
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: 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?
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
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
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: Select with CustomTO
I took a look to: http://wiki.apache.org/tapestry/Tapestry5HowtoSelectWithObjects That approach, in my humble opinion, is plain wrong. You have to retrieve a list of objects when you need just one of them (wrong) or put a list in a session (very wrong). Create one instance of OptionModelImpl for each of your options (objects) and pass them to a SelectModelImpl. Both of these Impl classes are in an internal package inside Tapestry. I have always wondered whether it is considered good practice to instantiate these internal classes directly in our code? Benny
T5.1 - Embedded JavaScript inside Zone
Hi everyone, I have a zone that contains some *dynamic* JavaScript that sets a global JavaScript object. However, Tapestry seems to be dropping the script block from the zone when it renders. I also tried to use RenderSupport.addScript() in the action link event handler that updates the zone, but got the error No object of type org.apache.tapestry5.RenderSupport is available from the Environment. My questions are: (1) Why does Tapestry not allow embedded script? I can't put the script in a file since it contains expansions ( e.g. location.name = ${location.name}; ) (2) What is the proper way to include dynamic JavaScript in zones? Thanks in advance, Benny
Re: T5.1 - Embedded JavaScript inside Zone
Thanks Norman, I'll try your suggestion. Thiago, I don't see your comments (except your friendly Hi). Could you respond again please? Thanks. Regards, Benny On Thu, Feb 4, 2010 at 5:50 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 04 Feb 2010 20:46:53 -0200, Benny Law benny.mk@gmail.com wrote: Hi everyone, Hi! from the zone when it renders. I also tried to use RenderSupport.addScript() in the action link event handler that updates the zone, but got the error No object of type org.apache.tapestry5.RenderSupport is available from the Environment. My questions are: (1) Why does Tapestry not allow embedded script? I can't put the script in a file since it contains expansions ( e.g. location.name = ${ location.name}; ) (2) What is the proper way to include dynamic JavaScript in zones? Thanks in advance, Benny -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, Ars Machina Tecnologia da Informação Ltda. Coordenador e professor da Especialização em Engenharia de Software com Ênfase em Java da Faculdade Pitágoras Consultor, desenvolvedor e instrutor em Java, Tapestry e Hibernate Sócio, 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: T5.1 - Embedded JavaScript inside Zone
Thanks Thiago. Norman's solution is working fine for me, so I will leave it like that. (I like keeping my JavaScript to the .tml file as much as possible to maintain a cleaner separation between the page template and the page class.) But thanks again for your suggestion. Your approach may come in handy for another problem. I am still wondering why Tapestry strips away all script unless it's in a block. Can anyone shed any light on this? Regards, Benny On Thu, Feb 4, 2010 at 6:08 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 04 Feb 2010 21:01:39 -0200, Benny Law benny.mk@gmail.com wrote: Thiago, I don't see your comments (except your friendly Hi). Could you respond again please? Thanks. Hi! :D I tripped over my keyboard and accidentally sent the message before finishing it. :P from the zone when it renders. I also tried to use RenderSupport.addScript() in the action link event handler that updates the zone, but got the error No object of type org.apache.tapestry5.RenderSupport is available from the Environment. RenderSupport is only available while rendering. My questions are: (2) What is the proper way to include dynamic JavaScript in zones? One way of doing it is creating a component containing what you want be in inside the zone. Then, in its @SetupRender method, user RenderSupport.addScript() to generate JavaScript lines. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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: T5.1 - Embedded JavaScript inside Zone
Yes, I'm pretty sure. In fact, I even tried moving the script element outside the zone, and found that it still didn't show up in the HTML response. It seems like the only way to preserve the script is to put it in a t:block. After wrapping my script with a t:block and adding a t:delegate right after the t:block, my code started to work. On Thu, Feb 4, 2010 at 6:40 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: On Thu, 04 Feb 2010 21:37:26 -0200, Benny Law benny.mk@gmail.com wrote: I am still wondering why Tapestry strips away all script unless it's in a block. Can anyone shed any light on this? I'm lazy to test it now, but are you sure it was stripped? Maybe it was included, but not automatically executed. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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: T5: How to periodically update a zone?
Hi Matias, I would use the same approach, except I would use a JavaScript function similar to this one to update the zone instead of firing a click event on the link: function updateZoneFromActionLink( actionLinkId ) { var actionLink = $(actionLinkId); Tapestry.findZoneManager( actionLink ).updateFromURL( actionLink.href ); } Regards, Benny On Tue, Feb 2, 2010 at 11:18 AM, matias.blasi matias.bl...@gmail.comwrote: Hi all, I'm trying to find the best way to do it. I can put an invisible actionlink with the zone parameter set, and with a little javascript timer fire a click event on that link. But it is no very clean, and the mouse event fire should be cross-browser... Have anyone a better solution? Regards, Matías. -- View this message in context: http://old.nabble.com/T5%3A-How-to-periodically-update-a-zone--tp27423077p27423077.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: Different ExceptionReport for different pages
I haven't tried it myself, but the Tapestry documentation says that you can create an event handler in your special page to catch exceptions and redirect to a different exception page: Object onException( Throwable cause ) { return MySpecialExceptionReport.class; } Don't know if this would help you in your case. Regards, Benny On Sun, Jan 17, 2010 at 2:54 PM, Howard Lewis Ship hls...@gmail.com wrote: This is easier in 5.2 as there's a new RequestGlobals property that identifies the name of the page for the request. On Sun, Jan 17, 2010 at 11:03 AM, Richard Hill r...@su3analytics.com wrote: Ok thanks. Is it possible to detect which page threw the exception? My logic needs to be based on the page that threw the exception as opposed to the type of exception. -Original Message- From: Thiago H. de Paula Figueiredo thiag...@gmail.com Reply-to: Tapestry users users@tapestry.apache.org To: Tapestry users users@tapestry.apache.org Subject: Re: Different ExceptionReport for different pages Date: Sun, 17 Jan 2010 16:25:09 -0200 On Sun, 17 Jan 2010 15:41:08 -0200, Richard Hill r...@su3analytics.com wrote: Hi All, Hi! I have an ExceptionReport.java, .tml to present a pretty error page to users. However there is one page where I would like to have a different exception page. Is this possible? Simple answer: you can, but I think it's not worth the hassle. Just use some logic in your error page to show different content to different exceptions. You can also redirect to another page in your ExceptionReport page. Sophisticated answer: override the RequestExceptionHandler service. Draw some inspiration from RequestExceptionHandlerImpl. - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Number Formatting in TextField (T5)
This was my first day of work after a long holiday break, and I finally got something reasonably clean that I can share. To recap, my goal was to create a generic solution for allowing precise control of the number format used in a TextField that can be customized per field instance. The approach I came up with is to create a special binding prefix that interprets the binding expression as a number pattern string (a non-localized pattern string as per DecimalFormat). The result is that I can now do things like t:textField t:id=latitude value=worksite.latitude translate=numberFormat:0.0 / and t:textField t:id=amount value=card.amount translate=numberFormat:#,##0.00 / with no custom code required in the page class, and the error messages can be overridden in the standard fashion if desired. The solution consists of 3 new classes: NumberFormatBindingFactory, NumberFormatBinding, and NumberTranslator. Here is the code: public class NumberFormatBindingFactory implements BindingFactory { private final FieldTranslatorSource fieldTranslatorSource; private final TypeCoercer typeCoercer; public NumberFormatBindingFactory( FieldTranslatorSource fieldTranslatorSource, TypeCoercer typeCoercer ) { this.fieldTranslatorSource = fieldTranslatorSource; this.typeCoercer = typeCoercer; } public Binding newBinding( String description, ComponentResources containerResources, ComponentResources fieldResources, String expression, Location location ) { return new NumberFormatBinding( fieldResources, expression, location, fieldTranslatorSource, typeCoercer ); } } public class NumberFormatBinding extends BaseLocatable implements Binding { private final Translator? translator; private final FieldTranslatorSource fieldTranslatorSource; private final Field field; private final String overrideId; private final Messages overrideMessages; private final Locale locale; private FieldTranslator? fieldTranslator; public NumberFormatBinding( ComponentResources fieldResources, String formatPattern, Location location, FieldTranslatorSource fieldTranslatorSource, TypeCoercer typeCoercer ) { super( location ); this.translator = createTranslator( fieldResources, formatPattern, typeCoercer ); this.fieldTranslatorSource = fieldTranslatorSource; this.field = (Field) fieldResources.getComponent(); this.overrideId = fieldResources.getId(); this.overrideMessages = fieldResources.getContainerMessages(); this.locale = fieldResources.getLocale(); } public Object get() { if (fieldTranslator == null) { // Create the FieldTranslator lazily to ensure FormSupport is present. fieldTranslator = fieldTranslatorSource.createTranslator( field, overrideId, overrideMessages, locale, translator ); } return fieldTranslator; } public void set( Object value ) { throw new UnsupportedOperationException(); } public Class? getBindingType() { return get().getClass(); } public boolean isInvariant() { return true; } public A extends Annotation A getAnnotation( ClassA annotationClass ) { return null; } private NumberFormat createNumberFormat( String pattern, Locale locale ) { DecimalFormatSymbols symbols = new DecimalFormatSymbols( locale ); DecimalFormat format = new DecimalFormat( pattern, symbols ); if (pattern.indexOf('.') 0) { format.setParseIntegerOnly( true ); } return format; } @SuppressWarnings(unchecked) private T extends Number TranslatorT createTranslator( ComponentResources fieldResources, String formatPattern, TypeCoercer typeCoercer ) { NumberFormat numberFormat = createNumberFormat( formatPattern, fieldResources.getLocale() ); ClassT numberType = fieldResources.getBoundType(value); if (numberType == null) { throw new IllegalStateException('value' parameter not bound for + fieldResources.getId() +; numeric type unknown.); } return new NumberTranslatorT( numberType, numberFormat, typeCoercer ); } } public class NumberTranslatorT extends Number implements TranslatorT { private static final ListClass? INTEGER_TYPES = Arrays.asList( new Class?[] { Byte.class, Short.class, Integer.class, Long.class, BigInteger.class }); private final ClassT type; private final NumberFormat formatter; private final TypeCoercer typeCoercer; private final String messageKey; public NumberTranslator( ClassT type,
Re: Number Formatting in TextField (T5)
On Thu, Dec 24, 2009 at 5:41 AM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: This is very clever! I guess it'll work. :) Just pay attention that the parameter received by the translate is a FieldTranslator, not a Translator itself. Thanks Thiago. I already found out the hard way, but it's basically working now :) The last thing I still need to figure out is the purpose of FieldTranslator (I read the doc but still didn't fully get it) and how I can allow the error messages to be overridden in the message catalogue on a per field basis in the standard manner. I guess I need to use some other service to do that. Any hint will be appreciated :)
Re: Number Formatting in TextField (T5)
Hi Thiago, I finally got some time to revisit this. I spent some time last night trying to subclass AbstractTextField as you suggested, but got lost. I would appreciate it if you or anybody else could give me some pointers. What I am trying to do is to create a NumericField by extending AbstractTextField and adding a format parameter which accepts a decimal format pattern. Using this pattern string, NumericField will provide a translator based on that pattern. Again, the motivation behind this is so that I can control precisely how many decimal places to display and whether group separators should be displayed. Where I got lost is figuring out how to provide the custom translator from within NumericField. Thanks in advance, Benny On Wed, Nov 18, 2009 at 8:11 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Wed, 18 Nov 2009 22:02:42 -0200, Benny Law benny.mk@gmail.com escreveu: If I need to implement it myself, I would like to know how best to provide this info to the translator on a per field basis. AFAIK, it's not possible. Should I create a NumericField component (subclass of TextField) and add parameters for this? Sublass AbstractTextField instead. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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: Number Formatting in TextField (T5)
Hi Thiago, I just thought of another idea and would like to bounce it off you. Instead of subclassing AbstractTextField to create NumericField, I can just use TextField as is, but define a new binding prefix for the translate parameter which will allow the format pattern to be specified as the binding expression, like this: t:textfield t:id=latitude translate=numberformat:0.0 / I will need to create a new BindingFactory to return a numeric translator that uses the specified format. What do you think? Will this work? Benny On Wed, Dec 23, 2009 at 11:32 AM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Wed, 23 Dec 2009 14:01:03 -0200, Benny Law benny.mk@gmail.com escreveu: Hi Thiago, Hi! should be displayed. Where I got lost is figuring out how to provide the custom translator from within NumericField. In this case, I think it would be easier to not use a translator and do the conversion yourself. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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: T5 / Ajax / ID generation
Hi, sorry for jumping in, but I ran into this before myself. I still don't quite understand the need for T5 to do this though: If the zone is being replaced during the update, how can element IDs be duplicated inside the zone? Losing control over element IDs is a bit inconvenient, and that's one of the (numerous) things I disliked about ASP.NET. Thanks for any light you can shed on this. Benny On Tue, Dec 15, 2009 at 4:20 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Tue, 15 Dec 2009 19:07:49 -0200, Gunnar Eketrapp gunnar.eketr...@gmail.com escreveu: Hi! Hi! Is there any way to prevent T5 from adding these numbers. The initally fields have been replaced so it should be safe to reuse the id names !!! I guess not. This is Tapestry trying to avoid having more than one element with the same id. Hint: use the class attribute instead of id in this case. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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: T5: handling form events in sub-components?
Hi Jacob, It sounds like you have nested forms which is not allowed. Benny On Thu, Dec 10, 2009 at 11:07 PM, Jacob Mouka jmo...@gmail.com wrote: Hi all (apologies if this is really obvious, but I can't find the info in the docs/examples) I have some sub-components (with form elements) in a form and I want to do some actions when the form is submitted. I've tried something like void onSubmit() { System.out.println(submitted); } but it doesn't get called on the sub-components, only the parent component. What am I missing? Thanks, Jacob - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Zone update effect in T5
Thanks Michael. I am using update=show now and it works. Benny On Thu, Dec 3, 2009 at 10:06 AM, Michael Gentry mgen...@masslight.netwrote: I believe the first reply by Hugo works: http://old.nabble.com/How-do-I-remove-the-yellow-fade-that-occurs-when-updating-the-Zone-component--tt23493373.html On Wed, Dec 2, 2009 at 8:37 PM, Benny Law benny.mk@gmail.com wrote: Can someone show me how I can turn off the fading yellow effect when a zone is updated? Thanks in advance. Benny Law - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Zone update effect in T5
Can someone show me how I can turn off the fading yellow effect when a zone is updated? Thanks in advance. Benny Law
Re: Zone update effect in T5
Thanks Dave. I can't believe I missed that in the component reference! Benny On Wed, Dec 2, 2009 at 9:07 PM, David Rees dree...@gmail.com wrote: On Wed, Dec 2, 2009 at 5:37 PM, Benny Law benny.mk@gmail.com wrote: Can someone show me how I can turn off the fading yellow effect when a zone is updated? Set the zone's update attribute to something other than the default. Frankly, I wish the default did not display any effects! t:zone update= /t:zone -Dave - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Number Formatting in TextField (T5)
Thanks Thiago. I was hoping that someone had already implemented a generic numeric translator that allowed formatting to be specified at the field level, e.g. number of decimal places, whether or not thousands separators should be displayed, etc. If I need to implement it myself, I would like to know how best to provide this info to the translator on a per field basis. Should I create a NumericField component (subclass of TextField) and add parameters for this? Benny On Tue, Nov 17, 2009 at 5:37 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Tue, 17 Nov 2009 20:12:22 -0200, Benny Law benny.mk@gmail.com escreveu: Is there a simpler way to do this, i.e. specify formatting for TextField? If custom Translators is the way to go, has anyone built something for numbers that reflects the current locale? Implement your own translator, as it probably will be used in many places in your application. -- Thiago H. de Paula Figueiredo Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and instructor Owner, software architect and developer, 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
Number Formatting in TextField (T5)
I am having some difficulty finding documentation and examples on how to control the formatting of numbers in TextField components. I have a page where I use two TextFields to display the latitude and longitude of a GPS location in decimal degrees. The default formatting provided by Tapestry only displays 3 decimal places, but I need 5. My current thinking is that I would need to create a Translator to use with these TextFields. Using the toClient event doesn't make sense because it's not reusable. Is there a simpler way to do this, i.e. specify formatting for TextField? If custom Translators is the way to go, has anyone built something for numbers that reflects the current locale? Thanks, Benny
Re: Getting ServletContext inside service
That depends on how your service is managed. I bind my service using the static binder in AppModule and use constructor arguments to inject what I need into my service object, and this works for me. Benny On Sat, Oct 31, 2009 at 4:47 AM, Stefan ste...@wammel.com wrote: Thanks Benny, i've tried that too, but it does not work. The context is null. Here's how i do it: @Inject private org.apache.tapestry5.services.Context context; Should that work? Stefan Am 30.10.2009 um 23:50 schrieb Benny Law: Hi Stefan, Try injecting org.apache.tapestry5.services.Context into your service and use its getInitParameter() method to retrieve your context parameters. Regards, Benny Law On Fri, Oct 30, 2009 at 3:56 PM, Stefan ste...@wammel.com wrote: Hi, is there a way to get access to the ServletContext inside a service bean? I like to configure some parameters within the web.xml which i need in some services. How can i retrieve these parameters? Injecting ApplicationGlobals does not work. Where is my mistake? Thanks in advance. Stefan
Re: Getting ServletContext inside service
Hi Stefan, Try injecting org.apache.tapestry5.services.Context into your service and use its getInitParameter() method to retrieve your context parameters. Regards, Benny Law On Fri, Oct 30, 2009 at 3:56 PM, Stefan ste...@wammel.com wrote: Hi, is there a way to get access to the ServletContext inside a service bean? I like to configure some parameters within the web.xml which i need in some services. How can i retrieve these parameters? Injecting ApplicationGlobals does not work. Where is my mistake? Thanks in advance. Stefan
T5.1 - Select component with validation error
Hello everyone, Is there any reason why the t-error CSS class is not assigned to a Select component when it is in error? Moreover, a Select component in error does not get the keyboard focus when the form is rendered. How can I fix this so that Select components get the same treatment as, say, TextField with regard to validation errors? Thanks, Benny Law
Conditional Validators
Hi everyone, I have a form with a field that is required only when certain conditions are true, so I can't use validator=required in the template. What is the best way to handle this? I would rather not do it in onValidateForm because that will require a duplicate error message to be provided (one that is already provided by the required validator). Is there a way to dynamically add validators to a field when a form is submitted before validations are performed? I am using T5.1. Thanks. Benny Law
Re: Conditional Validators
Thanks for your comments, guys. Benny On Mon, Oct 19, 2009 at 7:39 PM, Howard Lewis Ship hls...@gmail.com wrote: This is actually a challenge in Tapestry. In effect, the component abstraction does get in the way of any kind of intra-field dependency, including validation. In simpler systems, you can create an engineered coincidence for these types of relationships (the city field is required if a country is selected is easier to implement if you have orchestrated that the client id and control names are city and country and directly connect to the city and country properties of the data object). In Tapestry, a single form can reasonably edit many different data objects, and especially with loops and/or Ajax in the mix, the control names and client ids may vary wildly (including extra numbers to ensure that they are unique). I don't have a specific plan to address this; it may be something that is done less declaratively (using @Validate) and more imperatively (a set of utilities for generating the necessary client- and server-side validations). On Mon, Oct 19, 2009 at 2:57 PM, Ulrich Stärk u...@spielviel.de wrote: You can make form fields conditionally visible using the if or formfragment components. Apart from that, manually performing validation in the corresponding onValidate event handler method is the way to go. Uli Am 19.10.2009 23:10 schrieb Benny Law: Hi everyone, I have a form with a field that is required only when certain conditions are true, so I can't use validator=required in the template. What is the best way to handle this? I would rather not do it in onValidateForm because that will require a duplicate error message to be provided (one that is already provided by the required validator). Is there a way to dynamically add validators to a field when a form is submitted before validations are performed? I am using T5.1. Thanks. Benny Law - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! (971) 678-5210 http://howardlewisship.com - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Boolean Property Expression
Hi all, I just came across something that seems odd to me: I have a User object which has a Boolean property with isMobileUser() and setMobileUser(Boolean) as getter and setter. When I used ${user.mobileUser} in my template (user is a page property), Tapestry complained about the expression being write-only. Apparently, it did not recognize the getter with the is prefix. Changing the expression to ${user.isMobileUser()} fixed the problem. Can somebody confirm whether Tapestry recognizes the is getter prefix for Boolean (not boolean) properties? Thanks, Benny Law
Re: Boolean Property Expression
Thanks for your speedy response, Lance. I wish java.lang.Boolean were included. The reason I use that instead of primitive boolean is that I also use the User object for query by example in Hibernate, so I need to be able to set the property to null for the property to be ignored. I would appreciate your thoughts on this. Benny On Tue, Oct 13, 2009 at 12:48 PM, Lance Java lance.j...@googlemail.comwrote: The java beans spec only states that is can be used for boolean, it does not mention java.lang.Boolean. https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/viewproductdetail-start?productref=7224-javabeans-1.01-fr-spec-oth-js...@cds-cds_developer 2009/10/13https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/viewproductdetail-start?productref=7224-javabeans-1.01-fr-spec-oth-js...@cds-cds_developer%0a2009/10/13Benny Law benny.mk@gmail.com Hi all, I just came across something that seems odd to me: I have a User object which has a Boolean property with isMobileUser() and setMobileUser(Boolean) as getter and setter. When I used ${user.mobileUser} in my template (user is a page property), Tapestry complained about the expression being write-only. Apparently, it did not recognize the getter with the is prefix. Changing the expression to ${user.isMobileUser()} fixed the problem. Can somebody confirm whether Tapestry recognizes the is getter prefix for Boolean (not boolean) properties? Thanks, Benny Law
Re: Boolean Property Expression
Would it be reasonable to request that is be recognized as a valid getter prefix for java.lang.Boolean properties in Tapestry? (Hibernate allows it.) Howard? Benny On Tue, Oct 13, 2009 at 1:01 PM, Benny Law benny.mk@gmail.com wrote: Thanks for your speedy response, Lance. I wish java.lang.Boolean were included. The reason I use that instead of primitive boolean is that I also use the User object for query by example in Hibernate, so I need to be able to set the property to null for the property to be ignored. I would appreciate your thoughts on this. Benny On Tue, Oct 13, 2009 at 12:48 PM, Lance Java lance.j...@googlemail.comwrote: The java beans spec only states that is can be used for boolean, it does not mention java.lang.Boolean. https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/viewproductdetail-start?productref=7224-javabeans-1.01-fr-spec-oth-js...@cds-cds_developer 2009/10/13https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/viewproductdetail-start?productref=7224-javabeans-1.01-fr-spec-oth-js...@cds-cds_developer%0a2009/10/13Benny Law benny.mk@gmail.com Hi all, I just came across something that seems odd to me: I have a User object which has a Boolean property with isMobileUser() and setMobileUser(Boolean) as getter and setter. When I used ${user.mobileUser} in my template (user is a page property), Tapestry complained about the expression being write-only. Apparently, it did not recognize the getter with the is prefix. Changing the expression to ${user.isMobileUser()} fixed the problem. Can somebody confirm whether Tapestry recognizes the is getter prefix for Boolean (not boolean) properties? Thanks, Benny Law
Re: Accessing the T5 IoC Registry
Thanks Javier. This is actually what I ended up doing after doing more research. It seems to be the best approach. Regards, Benny On Fri, Oct 9, 2009 at 5:28 AM, Javier Molina jav...@comunicamultimedia.com wrote: You might want to contribute to the registry startup and initialize things there: http://tapestry.apache.org/tapestry5/tapestry-ioc/startup.html Benny Law escribió: Thanks Ben, this looks reasonably clean to me. Unless somebody else offers a better idea, I will probably go with this approach. Benny On Wed, Oct 7, 2009 at 10:08 AM, Ben Dotte ben.do...@gmail.com wrote: Here's a trick we use for this. We extend TapestryFilter and override init(Registry registry). Since this gets passed the created registry, we then store that in a static variable on our filter and provide a static getRegistry() method to retrieve it. This gets around the problem that TapestryFilter stores the registry in a private instance variable. To use your filter, just specify it in web.xml instead: filter filter-namet5/filter-name filter-classcom.whatever.MyFilter/filter-class /filter This still requires that the registry has been created at the point that it is requested, but at least you don't have to have access to the servlet context. Ben On Wed, Oct 7, 2009 at 6:58 AM, Benny Law benny.mk@gmail.com wrote: Thank you all for your help. This is why I need to do this: I have an immutable class called ProjectType, and it has a few predefined instances held in public static final fields (ProjectType.GD, ProjectType.TF, etc.) These instances need to be initialized with data from the database, so my approach was to do that inside the static initializer. However, I need to access the service that provides the database operations, and the service is registered in the IoC container. If anyone has a better idea, I will be glad to learn. I believe there are rare occasions when the registry is needed outside of normal injection, so having a convenient way to get to it in Tapestry would be nice, although it may open up opportunities for abuse. Benny Law On Wed, Oct 7, 2009 at 4:58 AM, Ben Gidley b...@gidley.co.uk wrote: You can get it from the servlet context - it adds it to a context variable. Registry registry = (Registry) getServletContext().getAttribute(TapestryFilter.REGISTRY_CONTEXT_NAME); This shouldn't really be used inside another service as it is a bit confusing. You may also have to make sure it doesn't get called until tapestry-ioc has initialised via the servlet filter otherwise the attribute won't be there yet. Ben Gidley www.gidley.co.uk b...@gidley.co.uk On Wed, Oct 7, 2009 at 9:37 AM, Alfie Kirkpatrick alfie.kirkpatr...@ioko.com wrote: You can inject ObjectLocator into a service but it doesn't sound like this would work for you as it's still essentially injection in the normal way. For webapps TapestryFilter doesn't put the registry in a static anywhere so there is no way to get the registry from 'outside' the dependency injection framework AFAIK. You could of course copy TapestryFilter, write your own, and put it into a static/threadlocal. Maybe you can explain why you have a static initialiser that needs the registry? It sounds very 'un-tapestry' ;-) Alfie. -Original Message- From: Benny Law [mailto:benny.mk@gmail.com] Sent: 07 October 2009 01:34 To: Tapestry Users Subject: Accessing the T5 IoC Registry Hello, How can I obtain a service from the IoC registry inside a static initializer? Injection doesn't seem to work with static members, so I need to access the registry directly, or is there a better way? Thanks, Benny Law - 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: Accessing the T5 IoC Registry
Thank you all for your help. This is why I need to do this: I have an immutable class called ProjectType, and it has a few predefined instances held in public static final fields (ProjectType.GD, ProjectType.TF, etc.) These instances need to be initialized with data from the database, so my approach was to do that inside the static initializer. However, I need to access the service that provides the database operations, and the service is registered in the IoC container. If anyone has a better idea, I will be glad to learn. I believe there are rare occasions when the registry is needed outside of normal injection, so having a convenient way to get to it in Tapestry would be nice, although it may open up opportunities for abuse. Benny Law On Wed, Oct 7, 2009 at 4:58 AM, Ben Gidley b...@gidley.co.uk wrote: You can get it from the servlet context - it adds it to a context variable. Registry registry = (Registry) getServletContext().getAttribute(TapestryFilter.REGISTRY_CONTEXT_NAME); This shouldn't really be used inside another service as it is a bit confusing. You may also have to make sure it doesn't get called until tapestry-ioc has initialised via the servlet filter otherwise the attribute won't be there yet. Ben Gidley www.gidley.co.uk b...@gidley.co.uk On Wed, Oct 7, 2009 at 9:37 AM, Alfie Kirkpatrick alfie.kirkpatr...@ioko.com wrote: You can inject ObjectLocator into a service but it doesn't sound like this would work for you as it's still essentially injection in the normal way. For webapps TapestryFilter doesn't put the registry in a static anywhere so there is no way to get the registry from 'outside' the dependency injection framework AFAIK. You could of course copy TapestryFilter, write your own, and put it into a static/threadlocal. Maybe you can explain why you have a static initialiser that needs the registry? It sounds very 'un-tapestry' ;-) Alfie. -Original Message- From: Benny Law [mailto:benny.mk@gmail.com] Sent: 07 October 2009 01:34 To: Tapestry Users Subject: Accessing the T5 IoC Registry Hello, How can I obtain a service from the IoC registry inside a static initializer? Injection doesn't seem to work with static members, so I need to access the registry directly, or is there a better way? Thanks, Benny Law - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Accessing the T5 IoC Registry
Hello, How can I obtain a service from the IoC registry inside a static initializer? Injection doesn't seem to work with static members, so I need to access the registry directly, or is there a better way? Thanks, Benny Law
Re: Reading context-params in T5
Thanks a lot guys! The Context service is a perfect fit in my case. Benny On Thu, Oct 1, 2009 at 3:17 AM, Robin Komiwes odiss...@gmail.com wrote: Just inject the Context service and use the getInitParameter method. On Thu, Oct 1, 2009 at 9:01 AM, Inge Solvoll inge.tapes...@gmail.com wrote: I believe you just have to inject SymbolSource into your class and get the parameter value from there. The ServletContextSymbolProvider should be on top of the situation :) On Wed, Sep 30, 2009 at 8:39 PM, Benny Law benny.mk@gmail.com wrote: Hello, I define the application version along with some other things as context-params in web.xml. What is the best way to read these parameters in T5? Thanks. Benny
Re: t5: popup window and pagelink
This may not be the best solution, but you could create an empty (and invisible) pagelink like a id='mylink' t:type='pagelink' page='mypage'/a and reference its href with $('mylink').href when opening the popup. You might also want to consider using simulated popups like Prototype Window ( http://prototype-window.xilinus.com). Benny On Fri, Oct 2, 2009 at 12:10 AM, Angelo Chen angelochen...@yahoo.com.hkwrote: Hi, I use following to open a pagelink page in another window: details Now I'd like to make it a popup, so I'm thinking of using: window.open(href, windowname, 'width=400,height=200,scrollbars=yes'); now, how to specify the pagelink in href field of window.open? Thanks -- View this message in context: http://www.nabble.com/t5%3A-popup-window-and-pagelink-tp25710259p25710259.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
Reading context-params in T5
Hello, I define the application version along with some other things as context-params in web.xml. What is the best way to read these parameters in T5? Thanks. Benny
T5 Hibernate
Hello, Can someone point me to the most up-to-date and detailed documentation on using Hibernate with T5 (but not Spring)? Thank you, Benny
Re: T5 Hibernate
Hi Thiago, Thanks for responding, but I was hoping for something a little more detailed. I had visited this link before, but needed more details on things such as configuration and code examples. I have an existing database, and would like to map my models to the existing tables using annotations. I would like to know what I need in terms of configuration and what to inject into my DAO's to get a Hibernate session. If you could give me a few more pointers, I would really appreciate it. Benny On Tue, Sep 29, 2009 at 3:32 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Tue, 29 Sep 2009 16:23:02 -0300, Benny Law benny.mk@gmail.com escreveu: Hello, Hi! Can someone point me to the most up-to-date and detailed documentation on using Hibernate with T5 (but not Spring)? http://tapestry.apache.org/tapestry5.1/tapestry-hibernate/ -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor http://www.arsmachina.com.br/thiago - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: T5 Hibernate
Thanks Thiago. Somehow, I missed those additional links in the left nav. Now I have a bit more info to go on. Benny On Tue, Sep 29, 2009 at 4:52 PM, Thiago H. de Paula Figueiredo thiag...@gmail.com wrote: Em Tue, 29 Sep 2009 17:00:34 -0300, Benny Law benny.mk@gmail.com escreveu: Hi Thiago, Hi! Thanks for responding, but I was hoping for something a little more detailed. I had visited this link before, but needed more details on things such as configuration and code examples. Configuration: http://tapestry.apache.org/tapestry5.1/tapestry-hibernate-core/conf.html I have an existing database, and would like to map my models to the existing tables using annotations. Use Hibernate Tools (Eclipse plugin) to generate the entity classes through database reverse engineering. I would like to know what I need in terms of configuration and what to inject into my DAO's to get a Hibernate session. Declare your DAOs as Tapestry-IoC services and have the Session injected in them. -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor http://www.arsmachina.com.br/thiago - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Preventing Form Resubmission
This is a very informative article. Thanks for sharing, Sebastian. Benny On Thu, Sep 24, 2009 at 7:32 AM, Sebastian Hennebrueder use...@laliluna.dewrote: Hello, I described an approach without using Javascript. http://www.laliluna.de/tapestry-webframework-evaluation-test.html Best Regards Sebastian Benny Law schrieb: Thanks Geoff. I can't access this link for some reason, but I'll try again later. Here is my JavaScript (feel free to critique): document.observe(dom:loaded, function() { $$(form).invoke(observe, submit, function(event) { if (this.submitted) { event.stop(); } else { this.submitted = true; }; }); }); Benny On Wed, Sep 23, 2009 at 6:09 PM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Tapestry doesn't. Here's a solution that uses a mixin. The mixin's JavaScript might be similar to yours. http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/creatingmixins1 Cheers, Geoff On 24/09/2009, at 7:34 AM, Thiago H. de Paula Figueiredo wrote: Em Wed, 23 Sep 2009 18:07:34 -0300, Benny Law benny.mk@gmail.com escreveu: I was wondering if Tapestry automatically prevents a form from being submitted more than once (like when you press the Enter key quickly a few times when you are in a text field)? In my quick test, it seemed that something was providing this protection. I have some JavaScript that will provide this safeguard (which I used in another non-Tapestry application), I don't think so, but I'm not 100% sure. -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor http://www.arsmachina.com.br/thiago - 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 -- Best Regards / Viele Grüße Sebastian Hennebrueder - Software Developer and Trainer for Hibernate / Java Persistence http://www.laliluna.de - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Preventing Form Resubmission
I was wondering if Tapestry automatically prevents a form from being submitted more than once (like when you press the Enter key quickly a few times when you are in a text field)? In my quick test, it seemed that something was providing this protection. I have some JavaScript that will provide this safeguard (which I used in another non-Tapestry application), but I would like to confirm if it will be needed. Thanks in advance. Benny
Re: Preventing Form Resubmission
Thanks Geoff. I can't access this link for some reason, but I'll try again later. Here is my JavaScript (feel free to critique): document.observe(dom:loaded, function() { $$(form).invoke(observe, submit, function(event) { if (this.submitted) { event.stop(); } else { this.submitted = true; }; }); }); Benny On Wed, Sep 23, 2009 at 6:09 PM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Tapestry doesn't. Here's a solution that uses a mixin. The mixin's JavaScript might be similar to yours. http://jumpstart.doublenegative.com.au:8080/jumpstart/examples/javascript/creatingmixins1 Cheers, Geoff On 24/09/2009, at 7:34 AM, Thiago H. de Paula Figueiredo wrote: Em Wed, 23 Sep 2009 18:07:34 -0300, Benny Law benny.mk@gmail.com escreveu: I was wondering if Tapestry automatically prevents a form from being submitted more than once (like when you press the Enter key quickly a few times when you are in a text field)? In my quick test, it seemed that something was providing this protection. I have some JavaScript that will provide this safeguard (which I used in another non-Tapestry application), I don't think so, but I'm not 100% sure. -- Thiago H. de Paula Figueiredo Independent Java consultant, developer, and instructor http://www.arsmachina.com.br/thiago - 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: Projects and sites powered by Tapestry
Pardon me if I am mistaken, but shouldn't .class and .tml files be under WEB-INF and hence inaccessible automatically? Benny On Thu, Sep 10, 2009 at 2:52 AM, martijn.list martijn.l...@gmail.comwrote: Angelo Chen wrote: how to close access to .class and .tml? This has been posted to the list multiple times so I another time wouldn't hurt ;) I use the following code to whitelist some assets. Access to non white listed assets is denied. Add to your application module: private static final String[] ASSET_WHITE_LIST = {jpg, jpeg, png, gif, js, css, ico}; /* * All the assets that are allowed to be downloaded using the assets service (including files without extension and dirs) */ private static final SetString assetsWhitelist = Collections.synchronizedSet( new HashSetString(Arrays.asList(ASSET_WHITE_LIST))); public void contributeHttpServletRequestHandler(OrderedConfigurationHttpServletRequestFilter configuration, @Inject @Value(${access-denied-page}) final String accessDeniedPage) { /* * Create a filter that will block access to some assets. The asset service allows access to some assets we do * not want to expose. The asset service will show all files in /assets/ directory and allows you (by default) * to download some files which you do not want to expose. */ HttpServletRequestFilter filter = new HttpServletRequestFilter() { public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler) throws IOException { String path = request.getServletPath(); if (path.startsWith(/assets) (!assetsWhitelist.contains( StringUtils.lowerCase(FilenameUtils.getExtension(path) { logger.warn(access to asset + path + denied); response.sendRedirect(request.getContextPath() + / + accessDeniedPage); return true; } return handler.service(request, response); } }; configuration.add(AssetProtectionFilter, filter , before:*); } Sergey Didenko wrote: BTW, it's worth to remind again everyone who is going to publish their site urls, to close the access to .class and .tml files . On Tue, Sep 8, 2009 at 6:46 PM, Massimo Lusetti mluse...@gmail.com wrote: On Tue, Sep 8, 2009 at 5:27 PM, Thiago H. de Paula Figueiredothiag...@gmail.com wrote: Hi! I guess this was already discussed some time ago, but I couldn't find it. :( Anyway, it's been a long time, so let's get it started again. ;) Tapestry is a wonderful framework, but it isn't the best known one around. Sometimes, managers ask us to provide some projects/sites/success stories/etc using it so they can be more confident about Tapestry. There's a Success Stories page in the wiki (http://wiki.apache.org/tapestry/SuccessStories), but it hasn't had any edit since 2007-10-05. What about sharing your success stories with us, promoting Tapestry (specially T5)? If the project is a public website, please post the URL here. I think we should have a list of Tapestry-powered sites. Thanks in advance. It would be great to have that page more up to date but i remember Howard asking for private user stories and more then one have replied him even personally so i guess if that would make sense too to have that stories online. Do i remember correctly Howard? -- Massimo http://meridio.blogspot.com - 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 -- Djigzo open source email encryption - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: Projects and sites powered by Tapestry
Thanks for the detailed info, Alex. There is so much to learn. I hope this hole gets patched soon. Benny On Thu, Sep 10, 2009 at 9:41 AM, Alex Kotchnev akoch...@gmail.com wrote: Benny, indeed that would be the case for a traditional web framework that serves web application assets (e.g. stylesheets, images, javascript) only from the publicly available directories (e.g. outside of WEB-INF). However, because of T5's component nature , if you deployed a component (e.g. as a jar in the web app) it might need to access assets from the classpath (e.g. from the component jar). Hence, currently there is a wide gaping security whole in a stock T5 application's Asset service, that it can access any files on the classpath (e.g. property files, .tml source, etc). There is an issue filed for this , some improvements in T5.1, and a few decent solutions (as the posting above mentions), but the framework is still very vulnerable. Cheers, Alex K On Thu, Sep 10, 2009 at 8:56 AM, Benny Law benny.mk@gmail.com wrote: Pardon me if I am mistaken, but shouldn't .class and .tml files be under WEB-INF and hence inaccessible automatically? Benny On Thu, Sep 10, 2009 at 2:52 AM, martijn.list martijn.l...@gmail.com wrote: Angelo Chen wrote: how to close access to .class and .tml? This has been posted to the list multiple times so I another time wouldn't hurt ;) I use the following code to whitelist some assets. Access to non white listed assets is denied. Add to your application module: private static final String[] ASSET_WHITE_LIST = {jpg, jpeg, png, gif, js, css, ico}; /* * All the assets that are allowed to be downloaded using the assets service (including files without extension and dirs) */ private static final SetString assetsWhitelist = Collections.synchronizedSet( new HashSetString(Arrays.asList(ASSET_WHITE_LIST))); public void contributeHttpServletRequestHandler(OrderedConfigurationHttpServletRequestFilter configuration, @Inject @Value(${access-denied-page}) final String accessDeniedPage) { /* * Create a filter that will block access to some assets. The asset service allows access to some assets we do * not want to expose. The asset service will show all files in /assets/ directory and allows you (by default) * to download some files which you do not want to expose. */ HttpServletRequestFilter filter = new HttpServletRequestFilter() { public boolean service(HttpServletRequest request, HttpServletResponse response, HttpServletRequestHandler handler) throws IOException { String path = request.getServletPath(); if (path.startsWith(/assets) (!assetsWhitelist.contains( StringUtils.lowerCase(FilenameUtils.getExtension(path) { logger.warn(access to asset + path + denied); response.sendRedirect(request.getContextPath() + / + accessDeniedPage); return true; } return handler.service(request, response); } }; configuration.add(AssetProtectionFilter, filter , before:*); } Sergey Didenko wrote: BTW, it's worth to remind again everyone who is going to publish their site urls, to close the access to .class and .tml files . On Tue, Sep 8, 2009 at 6:46 PM, Massimo Lusetti mluse...@gmail.com wrote: On Tue, Sep 8, 2009 at 5:27 PM, Thiago H. de Paula Figueiredothiag...@gmail.com wrote: Hi! I guess this was already discussed some time ago, but I couldn't find it. :( Anyway, it's been a long time, so let's get it started again. ;) Tapestry is a wonderful framework, but it isn't the best known one around. Sometimes, managers ask us to provide some projects/sites/success stories/etc using it so they can be more confident about Tapestry. There's a Success Stories page in the wiki (http://wiki.apache.org/tapestry/SuccessStories), but it hasn't had any edit since 2007-10-05. What about sharing your success stories with us, promoting Tapestry (specially T5)? If the project is a public website, please post the URL here. I think we should have a list of Tapestry-powered sites. Thanks in advance. It would be great to have that page more up to date but i remember Howard asking for private user stories and more then one have replied him even personally so i guess if that would make sense too to have that stories online. Do i remember correctly Howard? -- Massimo http://meridio.blogspot.com - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h
Re: Redirect page
I would try something like this: in B class... @PageAttached private void redirectToC() { // ... throw new RedirectException(...); // URL for C } You will need to create RedirectException. I believe there is something in the wiki on how to handle this exception in AppModule. Hope this helps. Benny On Thu, Sep 10, 2009 at 12:18 AM, Xuan Tran Le lexuanttk...@gmail.comwrote: I'm developing a project in portlet mode and I have a problem with page redirect: - I have 3 pages named A, B, C. - In page named A, I have a page link to page B, then I want B auto redirect to page C The problem is that in B class I don't know how to redirect to C. I try to call -- B class - @InjectPage private C c;//page C Object onActivate() { return c; } i don't know in B class which phase (which method) can redirect to other page. I did try add a action link to B, then when A call B, in B I click to the action link, then I have C. But I don't want to click page B again. I want to click page A then it call to B and in B it auto redirect to C.
Re: Redirect page
I wish it were built into Tapestry 5 too. It was in previous versions. I don't fully understand why Howard took it out, and I don't know of any built-in mechanism to abort the current page and redirect to another. I guess this is why somebody created the wiki entry. I followed it (with some modifications) and it works for me. Benny On Thu, Sep 10, 2009 at 12:54 AM, Xuan Tran Le lexuanttk...@gmail.comwrote: Thanks you so much. Maybe I have to follow this link: http://wiki.apache.org/tapestry/Tapestry5RedirectException Is there any built-in for this? I think that my problem is rather common. Why don't you make it be a tapestry built-in? On Thu, Sep 10, 2009 at 11:30 AM, Benny Law benny.mk@gmail.com wrote: I would try something like this: in B class... @PageAttached private void redirectToC() { // ... throw new RedirectException(...); // URL for C } You will need to create RedirectException. I believe there is something in the wiki on how to handle this exception in AppModule. Hope this helps. Benny On Thu, Sep 10, 2009 at 12:18 AM, Xuan Tran Le lexuanttk...@gmail.com wrote: I'm developing a project in portlet mode and I have a problem with page redirect: - I have 3 pages named A, B, C. - In page named A, I have a page link to page B, then I want B auto redirect to page C The problem is that in B class I don't know how to redirect to C. I try to call -- B class - @InjectPage private C c;//page C Object onActivate() { return c; } i don't know in B class which phase (which method) can redirect to other page. I did try add a action link to B, then when A call B, in B I click to the action link, then I have C. But I don't want to click page B again. I want to click page A then it call to B and in B it auto redirect to C.
Re: ValidateForm Event
Thanks Sebastian. I agree that only business logic related validation should go into onSuccess, and I would leave basic field validations to validators as much as possible. My problem with onValidateForm is still the amount of code I need to write to check for existing errors before I can do cross field validation. Let me give a quick example: Suppose I have two date fields, Start Date and End Date. I would use the built-in validators to check for missing values and invalid dates. However, in order to cross-validate these dates (to ensure Start Date is not later than End Date) in onValidateForm, I would need to inject the two fields, get the tracker from the form, and call inError() to find out if any of the dates are invalid (missing or bad syntax). If there are no errors, then I can compare the date properties bound to the fields. Do you see what I am getting at? Doing this in onSuccess is a lot easier since I won't need to check for existing errors, and I know that the date properties bound to the fields have been updated. Ideally, I would love to have another version of ValidateForm event which is fired before Success and only if there are no errors. Benny On Tue, Sep 1, 2009 at 3:39 PM, Sebastian Hennebrueder use...@laliluna.dewrote: Hello, the intended validation method for cross field validation is onValidateForm The onSuccess is probable the latest point to do validation. I would only place business logic related validation in there You may do field validation in the onValidateForm as well but it is normally simpler, faster and cleaner to do this using annotations. If you want to do field validation in the onValidateForm I would not follow the approach of newtonic and write if then statements but to create a simple builder (see Effective Java). Sample without reflection inside of the builder Validator userVal = ValidatorBuilder.required().minLenth(3).maxLength(60).build(); usage in onValidateForm userVal.validate(user.getName); You could leverage this using reflection -- Best Regards / Viele Grüße Sebastian Hennebrueder - Software Developer and Trainer for Hibernate / Java Persistence http://www.laliluna.de Benny Law schrieb: Hi Onno, I am all for clean and maintainable code, and that's why I think ValidateForm can be cleaner if I didn't need to check for field errors first. On the main Tapestry 5.1 page, the Login example calls the authenticator in onValidateForm, but the same example in the User Guide under Input Validation does that in onSuccess. I think the latter is correct; the former won't work properly because it acts on the properties bound to the fields which may not reflect the current field contents if there are field validation errors. To fix the first example, some code needs to be added to onValidateForm to check if the fields have passed field-level validations before invoking the authenticator. I hope this clarifies what I am thinking. Thanks. Benny On Mon, Aug 31, 2009 at 4:57 AM, Onno Scheffers o...@piraya.nl wrote: Thanks for your response. Could you explain what you mean by keeping my validation in the correct callback? I think it's about writing clean and maintainable code. For other developers reading back your code it makes more sense if you add your validation errors in the ValidateForm event and to perform some (database?) action in the success handler. The ValidateForm event is where validation errors are added and some of them are automatically taken care of for you by the Tapestry validator mechanism. If you don't want to add more than one error-message, you can easily check if the field is in error already. Sometimes it also makes sense to add mutiple errors per field since you're telling the user immediately what (s)he's doing wrong instead of having them re-submit again only to find yet another validation error on the same field. regards, Onno - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: ValidateForm Event
Thanks for alerting me, Geoff. But even the input validation example in the User Guide shows recording error in onSuccess()! I must say I'm a bit alarmed by these quirks. I hope I don't find too many more surprises when I get deeper into Tapestry 5.1. I am working on a critical application under a tight deadline, and I am counting on Tapestry to help me deliver. I used Tapestry 3 before and loved it, but 5 is a totally new framework. Benny On Tue, Sep 1, 2009 at 9:46 PM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Beware, there's a long-standing problem with recording errors in onSuccess(). https://issues.apache.org/jira/browse/TAPESTRY-1972 Geoff On 02/09/2009, at 7:59 AM, Benny Law wrote: Thanks Sebastian. I agree that only business logic related validation should go into onSuccess, and I would leave basic field validations to validators as much as possible. My problem with onValidateForm is still the amount of code I need to write to check for existing errors before I can do cross field validation. Let me give a quick example: Suppose I have two date fields, Start Date and End Date. I would use the built-in validators to check for missing values and invalid dates. However, in order to cross-validate these dates (to ensure Start Date is not later than End Date) in onValidateForm, I would need to inject the two fields, get the tracker from the form, and call inError() to find out if any of the dates are invalid (missing or bad syntax). If there are no errors, then I can compare the date properties bound to the fields. Do you see what I am getting at? Doing this in onSuccess is a lot easier since I won't need to check for existing errors, and I know that the date properties bound to the fields have been updated. Ideally, I would love to have another version of ValidateForm event which is fired before Success and only if there are no errors. Benny On Tue, Sep 1, 2009 at 3:39 PM, Sebastian Hennebrueder use...@laliluna.dewrote: Hello, the intended validation method for cross field validation is onValidateForm The onSuccess is probable the latest point to do validation. I would only place business logic related validation in there You may do field validation in the onValidateForm as well but it is normally simpler, faster and cleaner to do this using annotations. If you want to do field validation in the onValidateForm I would not follow the approach of newtonic and write if then statements but to create a simple builder (see Effective Java). Sample without reflection inside of the builder Validator userVal = ValidatorBuilder.required().minLenth(3).maxLength(60).build(); usage in onValidateForm userVal.validate(user.getName); You could leverage this using reflection -- Best Regards / Viele Grüße Sebastian Hennebrueder - Software Developer and Trainer for Hibernate / Java Persistence http://www.laliluna.de Benny Law schrieb: Hi Onno, I am all for clean and maintainable code, and that's why I think ValidateForm can be cleaner if I didn't need to check for field errors first. On the main Tapestry 5.1 page, the Login example calls the authenticator in onValidateForm, but the same example in the User Guide under Input Validation does that in onSuccess. I think the latter is correct; the former won't work properly because it acts on the properties bound to the fields which may not reflect the current field contents if there are field validation errors. To fix the first example, some code needs to be added to onValidateForm to check if the fields have passed field-level validations before invoking the authenticator. I hope this clarifies what I am thinking. Thanks. Benny On Mon, Aug 31, 2009 at 4:57 AM, Onno Scheffers o...@piraya.nl wrote: Thanks for your response. Could you explain what you mean by keeping my validation in the correct callback? I think it's about writing clean and maintainable code. For other developers reading back your code it makes more sense if you add your validation errors in the ValidateForm event and to perform some (database?) action in the success handler. The ValidateForm event is where validation errors are added and some of them are automatically taken care of for you by the Tapestry validator mechanism. If you don't want to add more than one error-message, you can easily check if the field is in error already. Sometimes it also makes sense to add mutiple errors per field since you're telling the user immediately what (s)he's doing wrong instead of having them re-submit again only to find yet another validation error on the same field. regards, Onno - To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org
Re: ValidateForm Event
That looks very reasonable. I think I will adopt this approach. Thanks Geoff. Benny On Wed, Sep 2, 2009 at 1:02 AM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Yes, let's hope the doco is updated soon! https://issues.apache.org/jira/browse/TAP5-812 As for your conundrum, is there a reason you're not happy to do the following? It's only a few lines and its intention seems very clear. @Component(id = searchForm) private Form _form; void onValidateForm() { if (_form.getHasErrors()) { return; } ... Geoff http://jumpstart.doublenegative.com.au:8080/jumpstart/ On 02/09/2009, at 12:20 PM, Benny Law wrote: Thanks for alerting me, Geoff. But even the input validation example in the User Guide shows recording error in onSuccess()! I must say I'm a bit alarmed by these quirks. I hope I don't find too many more surprises when I get deeper into Tapestry 5.1. I am working on a critical application under a tight deadline, and I am counting on Tapestry to help me deliver. I used Tapestry 3 before and loved it, but 5 is a totally new framework. Benny On Tue, Sep 1, 2009 at 9:46 PM, Geoff Callender geoff.callender.jumpst...@gmail.com wrote: Beware, there's a long-standing problem with recording errors in onSuccess(). https://issues.apache.org/jira/browse/TAPESTRY-1972 Geoff On 02/09/2009, at 7:59 AM, Benny Law wrote: Thanks Sebastian. I agree that only business logic related validation should go into onSuccess, and I would leave basic field validations to validators as much as possible. My problem with onValidateForm is still the amount of code I need to write to check for existing errors before I can do cross field validation. Let me give a quick example: Suppose I have two date fields, Start Date and End Date. I would use the built-in validators to check for missing values and invalid dates. However, in order to cross-validate these dates (to ensure Start Date is not later than End Date) in onValidateForm, I would need to inject the two fields, get the tracker from the form, and call inError() to find out if any of the dates are invalid (missing or bad syntax). If there are no errors, then I can compare the date properties bound to the fields. Do you see what I am getting at? Doing this in onSuccess is a lot easier since I won't need to check for existing errors, and I know that the date properties bound to the fields have been updated. Ideally, I would love to have another version of ValidateForm event which is fired before Success and only if there are no errors. Benny On Tue, Sep 1, 2009 at 3:39 PM, Sebastian Hennebrueder use...@laliluna.dewrote: Hello, the intended validation method for cross field validation is onValidateForm The onSuccess is probable the latest point to do validation. I would only place business logic related validation in there You may do field validation in the onValidateForm as well but it is normally simpler, faster and cleaner to do this using annotations. If you want to do field validation in the onValidateForm I would not follow the approach of newtonic and write if then statements but to create a simple builder (see Effective Java). Sample without reflection inside of the builder Validator userVal = ValidatorBuilder.required().minLenth(3).maxLength(60).build(); usage in onValidateForm userVal.validate(user.getName); You could leverage this using reflection -- Best Regards / Viele Grüße Sebastian Hennebrueder - Software Developer and Trainer for Hibernate / Java Persistence http://www.laliluna.de Benny Law schrieb: Hi Onno, I am all for clean and maintainable code, and that's why I think ValidateForm can be cleaner if I didn't need to check for field errors first. On the main Tapestry 5.1 page, the Login example calls the authenticator in onValidateForm, but the same example in the User Guide under Input Validation does that in onSuccess. I think the latter is correct; the former won't work properly because it acts on the properties bound to the fields which may not reflect the current field contents if there are field validation errors. To fix the first example, some code needs to be added to onValidateForm to check if the fields have passed field-level validations before invoking the authenticator. I hope this clarifies what I am thinking. Thanks. Benny On Mon, Aug 31, 2009 at 4:57 AM, Onno Scheffers o...@piraya.nl wrote: Thanks for your response. Could you explain what you mean by keeping my validation in the correct callback? I think it's about writing clean and maintainable code. For other developers reading back your code it makes more sense if you add your validation errors in the ValidateForm event and to perform some (database?) action in the success handler. The ValidateForm event is where
Re: ValidateForm Event
Hi Onno, I am all for clean and maintainable code, and that's why I think ValidateForm can be cleaner if I didn't need to check for field errors first. On the main Tapestry 5.1 page, the Login example calls the authenticator in onValidateForm, but the same example in the User Guide under Input Validation does that in onSuccess. I think the latter is correct; the former won't work properly because it acts on the properties bound to the fields which may not reflect the current field contents if there are field validation errors. To fix the first example, some code needs to be added to onValidateForm to check if the fields have passed field-level validations before invoking the authenticator. I hope this clarifies what I am thinking. Thanks. Benny On Mon, Aug 31, 2009 at 4:57 AM, Onno Scheffers o...@piraya.nl wrote: Thanks for your response. Could you explain what you mean by keeping my validation in the correct callback? I think it's about writing clean and maintainable code. For other developers reading back your code it makes more sense if you add your validation errors in the ValidateForm event and to perform some (database?) action in the success handler. The ValidateForm event is where validation errors are added and some of them are automatically taken care of for you by the Tapestry validator mechanism. If you don't want to add more than one error-message, you can easily check if the field is in error already. Sometimes it also makes sense to add mutiple errors per field since you're telling the user immediately what (s)he's doing wrong instead of having them re-submit again only to find yet another validation error on the same field. regards, Onno
Re: ValidateForm Event
Thanks for your response. Could you explain what you mean by keeping my validation in the correct callback? Benny Law On Sun, Aug 30, 2009 at 1:40 AM, newtonik newto...@gmail.com wrote: I think you should use the onValidateForm for both field level and cross-field validation to keep your validation in the correct callback. I would just use nested loops to first check for field level validation then if successful, perform cross field validation. Benny Law wrote: Hello, I am new to Tapestry 5 and have a question about the ValidateForm event. I understand that this event is where cross-field validations should be done, but I find that before I can do the validations, I first need to check if there are any field-level validation errors with those fields that I want to cross validate. To avoid this extra work, I end up doing my cross-field validations in the Success event instead. It seems to me that the ValidateForm event would be more useful if it was triggered only when there are no field validation errors, similar to the Success event. Did I miss something, or are there others who share my view? Thanks in advance, Benny Law -- View this message in context: http://www.nabble.com/ValidateForm-Event-tp25205192p25208900.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
ValidateForm Event
Hello, I am new to Tapestry 5 and have a question about the ValidateForm event. I understand that this event is where cross-field validations should be done, but I find that before I can do the validations, I first need to check if there are any field-level validation errors with those fields that I want to cross validate. To avoid this extra work, I end up doing my cross-field validations in the Success event instead. It seems to me that the ValidateForm event would be more useful if it was triggered only when there are no field validation errors, similar to the Success event. Did I miss something, or are there others who share my view? Thanks in advance, Benny Law