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

Reply via email to