New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid calling UIInput.setValid(false) on all unmatched components when using <o:validateBean showMessageFor="@violating" .../> #352

Closed
ghost opened this Issue Feb 3, 2017 · 1 comment

Comments

Projects
None yet
1 participant
@ghost

ghost commented Feb 3, 2017

Hello Bauke,

I have a use-case where a bean is being validated using <o:validateBean showMessageFor="@violating" .../>, and this bean has several properties which are not associated with any input components on the form, and this bean will fail validation until some business logic takes place during a valueChange Ajax listener. During that time which validation may fail for undisplayed properties, all of the components are marked as invalid, and this looks confusing to the user.

Simplified example:

class Bean {
    @NotNull String value1;
    String value2;
    @NotNull String value3;
}

class Controller {
    void updateValue3(AjaxBehaviorEvent event) {
        bean.value3 = "pass";
    }
}

<h:form>
  <h:messages/>

  <h:inputText id="val1" value="#{bean.value1}">
    <f:ajax listener="#{controller.updateValue3}" render="@form"/>
  </h:inputText>

  <h:inputText id="val2" value="#{bean.value2}">
    <f:ajax render="@form"/>
  </h:inputText>

  <h:commandButton>
    <f:ajax execute="@form" render="@form"/>
    <o:validateBean value="#{bean}" showMessageFor="@violating"/>
  </h:commandButton>
</h:form>
  1. The user ignores the val1 input and proceeds to click the command button.
  2. Two ConstraintViolations occur in o:validateBean, CV1 and CV2:
    • CV1 is on value1 because of it's @NotNull annotation.
    • CV2 is on value3 because of it's @NotNull annotation.
  3. For CV1, o:validateBean locates component val1, and calls setValid(false), and sends the message with val1 clientId.
  4. For CV2, o:validateBean cannot locate any UIComponent, so it fallsback on showMessageFor="@form"-like behavior:
  5. @form fallback behavior calls setValid(false) on all UIComponents where value property base matches o:validateBean's value, both val1 and val2.
  6. @form fallback behavior then sends the message to the UIForm.

I'd like to eliminate step 5 since val2 is actually valid.

I'd also like to eliminate step 6 since redundantly, the generic, unlabeled "may not be null" message from CV2 gets rendered by the h:messages component, just below the labeled message for CV1, further confusing the user.

@BalusC

This comment has been minimized.

Show comment
Hide comment
@BalusC

BalusC Oct 14, 2017

Member

I decided to make this the default behavior for @violating, which is indeed more natural. As this is a breaking change, I've implemented it for OmniFaces 3.0, not 2.x.

Member

BalusC commented Oct 14, 2017

I decided to make this the default behavior for @violating, which is indeed more natural. As this is a breaking change, I've implemented it for OmniFaces 3.0, not 2.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment