Search code examples
javaformstapestry

Tapestry validation on disabled field


I basically have a textfield which may not be empty, so I added this validation:

t:validate="required"

(I actually have a few more validation criteria but they aren't relevant here). However, this field can also sometimes be disabled (it is bound to a property in the Java code):

t:disabled="isFieldADisabled"

Additionally the value is bound to a property:

t:value="entity.fieldA"

It's designed so that the property is never empty when the field is disabled. However, when the field is disabled, I can't submit the form - even though there's something displayed in the textbox. I don't know what's going on here, but I then tried to manually validate, like that:

@OnEvent(value = EventConstants.VALIDATE)
void onValidate(){
    if (isFieldADisabled)
        // What should I do here?
}

As my comment points out, I'm not sure what to do in there. As an additional complication this whole thing is in a container, which itself is contained in a form - so I don't really have access to the form itself from the onValidate method.

I suspect this is a general issue, if it's not please let me know whether you need more information.

EDIT I have evaluated the state of the textfield in onPrepareForSubmitFromEditForm:

As you can see the field is indeed disabled and its value is not even empty. However in onValidateFromEditForm tge value for disabled is actually false, but the value for the field still is not empty.


Solution

  • If your component is inside a form you can use one of the built-in environmental services available to components during rendering/form submission, i.e. ValidationTracker. Using the service it's possible to record form validation errors manually, i.e. ValiadationTracker#recordError(Field field, String message).

    Such components won't receive the VALIDATE event by default though, as this event is triggered on the Form component itself and bubbles up to its containers. This event is used for cross-form validation, when you need to implement custom validation for multiple fields. You can still use ValidationTracker to record validation errors.

    As for the disabled property of AbstractField, if its value is true the component won't participate in validation, neither client-side, nor server-side:

    If true, then the field will render out with a disabled attribute (to turn off client-side behavior). When the form is submitted, the bound value is evaluated again and, if true, the field's value is ignored (not even validated) and the component's events are not fired.