That's awesome ! Once again Cezary you have been quick and precise. Thank you so much for the solution and the detail explanation with code example. It really helped. It worked after I renamed onValidate method.
Thank you for attention to details and other suggestion. Much much appreciated. On Mon, Jun 13, 2016 at 10:56 AM, Cezary Biernacki <cezary...@gmail.com> wrote: > Even simpler solution is to remove your "onValidate" method and just use > Tapestry's "required" validator: > > "<t:textfield t:id="name" value="theZone.name" > t:validate="required,maxlength=50"/> > > You can customise the error message by putting an appropriate entry in your > message catalog (see > > http://tapestry.apache.org/forms-and-validation.html#FormsandValidation-CustomizingValidationMessages > ): > > name-required=You must enter a name. > > Cezary > > > On Mon, Jun 13, 2016 at 4:47 PM, Cezary Biernacki <cezary...@gmail.com> > wrote: > > > A correction, this part: > > void onValidateFromName(TaxZone z) { > > if (z.getName() == null || z.getName().trim().length() > > == 0) { > > form.recordError(nameField, "You must enter a name."); > > } > > } > > > > should be actually: > > void onValidateFromName(String name) { > > if (name == null || name.trim().length() > > == 0) { > > form.recordError(nameField, "You must enter a name."); > > } > > } > > > > > > On Mon, Jun 13, 2016 at 4:38 PM, Cezary Biernacki <cezary...@gmail.com> > > wrote: > > > >> Hi, > >> your "onValidate" method does not specify for which component it should > >> be invoked, so it is invoked for all components that trigger "validate" > >> event. Tapestry invokes validate for each input form control (providing > an > >> input value as the context argument) plus one for the whole form itself > >> with all data filled for cross-data validation. It is why observed that > >> your method was invoked twice. I believe that Tapestry 5.1 used to > trigger > >> separate "validateForm" event, but it was changed around Tapestry 5.3. > >> > >> You can fix this by specifying the component. It can be either the input > >> component (in this case you need to validate the context argument): > >> > >> void onValidateFromName(TaxZone z) { > >> if (z.getName() == null || z.getName().trim().length() > >> == 0) { > >> form.recordError(nameField, "You must enter a name."); > >> } > >> } > >> > >> or your form: > >> void onValidateFromHERE_YOUR_FORM_NAME() { > >> if (theZone.getName() == null || theZone.getName().trim(). > >> length() > >> == 0) { > >> form.recordError(nameField, "You must enter a name."); > >> } > >> } > >> > >> > >> (replace with HERE_YOUR_FORM_NAME with actual name of your form from > >> .tml - t:id argument) > >> > >> > >> > >> BTW, expression "x == null || x.trim().length() == 0" can be replaced > >> with StringUtils.isBlank(x) from Apache Commons library, e.g: > >> > >> void onValidateFromHERE_YOUR_FORM_NAME() { > >> if (StringUtils.isBlank(theZone.getName())) { > >> form.recordError(nameField, "You must enter a name."); > >> } > >> } > >> > >> Best regards, > >> Cezary > >> > >> > >> > >> On Mon, Jun 13, 2016 at 4:07 PM, sheikh hossain <shossa...@gmail.com> > >> wrote: > >> > >>> Hi, > >>> > >>> Our application has a page which submits a form through a submit button > >>> and > >>> it goes through the page 'onValidate' and fails the validation. > >>> > >>> the .tml file has > >>> > >>> <tc:groupbox> > >>> <table> > >>> - - - - - - > >>> - - - - - > >>> <td valign="center"><tc:genbutton><input t:type="submit" > >>> t:id="submit" t:mixins="common/blockingClick" > >>> value="${message:button.save}"/></tc:genbutton></td> > >>> > >>> <td valign="center"><tc:genbutton><a t:type="actionLink" > >>> t:id="cancel" > >>> > >>> > t:mixins="common/blockingClick">${message:button.cancel}</a></tc:genbutton></td> > >>> > >>> - - - - - - - - - > >>> - - - - - - - - > >>> > >>> <t:label for="name"><font > >>> size="+0"><b>${message:name-label}</b> * </font></t:label> > >>> > >>> <td> > >>> <t:textfield t:id="name" value="theZone.name" > >>> t:validate="maxlength=50"/> > >>> </td> > >>> > >>> > >>> In our page file: > >>> > >>> @Property > >>> // @Persist(PersistenceConstants.FLASH) --- I tested with this > also. > >>> doesn't work. > >>> private TaxZone theZone; > >>> > >>> > >>> - - - - - - > >>> - - - - - - > >>> > >>> void onActivate(final Long aRowId) throws SQLException { > >>> > >>> if (theZone == null) { > >>> if (rowid == null || rowid == -1L) { > >>> theZone = new TaxZone(""); > >>> }else{ > >>> // get from db > >>> } > >>> - - - - - > >>> - - - - - - > >>> > >>> void onValidate() { > >>> if (theZone.getName() == null || > >>> *theZone.getName().trim().length() > >>> == 0*) { > >>> form.recordError(nameField, "You must enter a name."); > >>> } > >>> } > >>> > >>> Even if we put a value into the text filed it comes back to the page > >>> after > >>> validation and shows 'You must enter a name' message. > >>> > >>> I have bebugged through the code and it seems that after submitting the > >>> form with a value entered into the name field the flow goes through the > >>> 'onActivate' and creates an empty 'theZone' and then gets validated > which > >>> creates the error message. After that only the flow populates 'theZone' > >>> with the value I had entered and gets validated again through the > >>> 'onValidate' method for the second time and get passed. But since it > >>> already has an error message in it's first 'onValidate' call it comes > >>> back > >>> to the page and shows the error message. > >>> > >>> I have tried with removing the code block from 'onActivate' and putting > >>> that into the 'setupRender' and in this case the flow throws a > >>> 'NullPointerException' in 'onValidate' since it couldn't find an > instance > >>> of 'theZone'. > >>> > >>> Also tried with @Persist for the 'theZone' property. That didn't work. > >>> > >>> It seems after the form submit with a value 'theZone' doesn't get > >>> initialized with the entered value. And if it's already initialized > >>> through > >>> the 'onActivate' code it doesn't get populated with the entered name > >>> before > >>> the 'onValidate' call. > >>> > >>> This code used to work in our old Tapestry 5.1.0.5. We are upgrading to > >>> version 5.4.0 > >>> > >>> I wonder if this is related to javascript update in new Tapestry > >>> framework > >>> or I am missing something to make it work. > >>> > >>> I would appreciate any response. > >>> > >>> Thanks a lot. > >>> > >> > >> > > >