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