0
votes

I use jsf 2.1.21, ICEFaces 3.3, Tomcat 7 and hibernate validator 5.1. Component ace:simpleSelectOneMenu refers to backing bean field which has @Min validation configured. And no bean validation is performed.

<ace:simpleSelectOneMenu id="category" value="#{myBean.catId}" label="Category"
                         validatorMessage="Please select category">
   <f:selectItem itemValue="-1" itemLabel="Please select"/>
   <f:selectItem itemValue="0" itemLabel="Category 1"/>
   <f:selectItem itemValue="1" itemLabel="Category 2"/>      
</ace:simpleSelectOneMenu>
<h:message id="categoryMsg" for="category"/>

@ManagedBean
public class MyBean {

  @Min(0)
  private int catId;

  public int getCatId() {
     return catId;
  }

  public void setCatId(int catId) {
     this.catId = catId;
  }
}

If use h:selectOneMenu instead of ace:simpleSelectOneMenu then bean validation works. Even more I see that ace SelectOneMenu component has validator javax.faces.validator.BeanValidator added to its validators. But it is not triggered.

I wonder how to make that validator work? If use other ace components like ace:textEntry then bean validation works.

1

1 Answers

1
votes

As a possible solution could be used valueChangeListener of ace:simpleSelectOneMenu.

It is called in validate phase. And for component is created validator javax.faces.validator.BeanValidator by jsf. So valueChangeListener just may pass through all validators of the component and trigger ones of BeanValidator type. Catching ValidatorException and calling FacesContext.validationFailed() simulates validation failure and no update model phase will be called.

<ace:simpleSelectOneMenu valueChangeListener="#{myBean.validateBean}">

@ManagedBean
public class MyBean {
    ...
    public void validateBean(ValueChangeEvent ve) {
        UIInput input = (UIInput) ve.getComponent();
        FacesContext context = FacesContext.getCurrentInstance();
        Validator[] validators = input.getValidators();

        for (Validator validator : validators) {
            if (validator instanceof BeanValidator) {
                try {
                    validator.validate(context, input, ve.getNewValue());
                }
                catch (ValidatorException e) {
                    input.setValid(false);
                    String txt = input.getValidatorMessage();
                    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,  txt, txt);
                    context.addMessage(input.getClientId(), message);
                    context.validationFailed();
                }
            }
        }
    }