These working examples might help too. http://jumpstart.doublenegative.com.au/jumpstart7/examples/input/programmaticvalidation <http://jumpstart.doublenegative.com.au/jumpstart7/examples/input/programmaticvalidation> http://jumpstart.doublenegative.com.au/jumpstart7/examples/input/validators <http://jumpstart.doublenegative.com.au/jumpstart7/examples/input/validators>
Geoff > On 14 Jun 2016, at 1:02 AM, sheikh hossain <shossa...@gmail.com> wrote: > > 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. >>>>> >>>> >>>> >>> >>