Why are immutable component validators named?

I have an IceFaces form and several input fields.

Let's say I have this:

<ice:selectOneMenu id="accountMenu"
    value="#{accountController.account.aId}"
    validator="#{accountController.validateAccount}">
    <f:selectItems id="accountItems"
            value="#{accountController.accountItems}" />
</ice:selectOneMenu>

      

and this:

<ice:selectOneMenu id="costumerMenu"
    value="#{customerController.customer.cId}"
    validator="#{customerController.validateCustomer">
    <f:selectItems id="customerItems"
            value="#{customerController.customerItems}" />
</ice:selectOneMenu>

      

If I change one value, the corresponding validator is called, which is good. But another validator is also called, which is not a good thing because the user gets an annoying message to insert a value into a field they may have just noticed. It's like pushing the user out with a "Hurry up now!" Stick. BAD!

I thought the "partialSubmit" attribute controls this behavior, so only one DOM part is sent that is affected by user interaction, but if I declare both components to be partially exposed, nothing changes. However, both validators are called if the same component value changes.

How can I prevent the entire form from being validated before it is fully submitted?

+2


a source to share


2 answers


When a partial request is made, the full JSF lifecycle is still running. Thus, the verification phase is still being processed and all components in the component hierarchy are verified.

There are good reasons for this. Changing one component can lead to a (potentially invalid) change in another component. For example, choosing from selectOneMenu

can set the value to inputText

.

ICEfaces changes handling in one important way: during partial submission, ICEfaces temporarily marks all components other than those that have activated sumbit as optional ( required="false"

). Thus, "required" checks are skipped. However, ICEfaces does not disable other checks.

There are two possible solutions to this problem:



  • Install immediate="true"

    in addition to partialSubmit

    . This slightly changes the lifecycle of the component when a partial request is made to perform validation in the request phase of the claim. This can lead to missing other checks.

  • Detecting if a partial sender happened in your custom validator. Skip validation if it is not the component that caused the partial submit. Unfortunately, there is no documentation on how to detect partial submit, but I found a solution in the source code for the class com.icesoft.faces.application.PartialSubmitPhaseListener

    .

    It turns out that ICEfaces adds two query parameters when doing the partial view:

    • ice.submit.partial

      - set to "true" to indicate that the partial request has been completed.
    • ice.event.captured

      - contains the component id of the component that generated the partial submit.

You can use these two parameters in your validation methods. Here's an example:

public void validateAccount(FacesContext context, 
  UIComponent component, Object value) 
{
  if(!partiallySubmitted(context) || 
     componentWasPartiallySubmitted(context, component)
    // Perform validation
  }

}

public boolean partiallySubmitted(FacesContext context) {
    ExternalContext externalContext = context.getExternalContext();
    Map parameterMap = externalContext.getRequestParameterMap();   

    return "true".equals(parameterMap.get("ice.submit.partial"));
}

public boolean componentWasPartiallySubmitted(FacesContext context, 
  UIComponent component) {
    ExternalContext externalContext = context.getExternalContext();
    Map parameterMap = externalContext.getRequestParameterMap();   

    String componentId = (String) parameterMap.get("ice.event.captured");

    return component.getClientId(context).equals(componentId);
}

      

Of course, direct access to the two query parameters is probably not supported. However, until the ICEfaces team provides a supported way to "discover" the partial view, this may be your only option.

+5


a source


Try to do ajax validation on the event onblur

(not sure how to do this with icy surfaces, but with rich interfaces it's easy <a4j:support event="onblur" />

)



0


a source







All Articles