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. >>> >> >> >