2

Im am using bean validation with JSF2.0. I have a validation group which I specify depending on a few conditions and link to a attribute in the managed bean. The attribute is assigned when the page first loads and works correctly (i.e. when the form is submitted the correct groups are validated). However if I change this property the validation groups are not updated and whatever the original value was set to will be used.

for example: JSF fragment:

<h:selectOneMenu id="unitOfMerchandise" value="#itemManager[targetBean].unitOfMerchandise}">
    <f:selectItem itemLabel="-- select --" itemValue="" />
    <f:selectItems value="#{itemManager.unitsOfMerchandise}" />
    <f:validateBean   validationGroups="#{itemManager.validatorClass}"  />
 </h:selectOneMenu>

Method:

@ManagedBean
@ViewScoped
public class ItemManager implements Serializable {
private String validatorClass = "com.rcs.itemmngr.model.validation.RegularItem"
private OpenItemRequest openItemRequest


private void onItemTypeSelected() {

        validatorClass = itemManagerModel.getValidatorItemRequestClass(openItemRequest).getName();

}
///getters setters
}

Any ideas on how to get this to work? I have also looked for a way to change the validation groups programmatically in the managed bean but with no joy.

Vikas V
  • 3,176
  • 2
  • 37
  • 60

1 Answers1

0

f:validateBean gruops are evaluated once: when the component tree is built. There seem to be no simple way to update them.

  • You can either update them manually per component:

    //bind you component here
    EditableValueHolder input;    
    
    //call this to update groups         
    public void setValidationGroups(String validationGroups) {
        for (Validator validator : input.getValidators()) {
            if (!(validator instanceof BeanValidator)) {
                 continue;
            }
            BeanValidator beanValidator = (BeanValidator) validator;
            beanValidator.setValidationGroups(validationGroups);
        }
    }
    
  • Or you can use approach described in this article: Delete the components holding unwanted state

    The idea is to remove components with f:validateBean from tree, so they will be reinitialized on rendering with new groups:

    parentComponent.getChildren().clear();
    

    e.g. if you are executing and rendering a section, you can call somethig like this in actionListner:

    public void resetContactsValidationGroups() {
       FacesContext ctx = FacesContext.getCurrentInstance();
       Iterator<String> ids = ctx.getPartialViewContext().getExecuteIds().iterator();
       while (ids.hasNext()) {
           ctx.getViewRoot().findComponent(ids.next()).getChildren().clear();
       }
    }
    
Yury Kisliak
  • 429
  • 3
  • 13