通过ajax禁用验证器

I have a simple request scoped entity / pojo which has a Enum and a String as properties.

public Enum Type
{
    None,
    Email,
    Fax;
}

@ManagedBean(name = "testEntity")
@RequestScoped
public class TestEntity
{
    private Type type; //Default = None
    private String address;

    //getter and setter
}

This Enum has a field 'Email' which identifies a e-mail address with a related address.
In JSF I now want to enable/disable a validator of a address InputText field regarding the currently selected type in a SelectOneMenu.

<h:form id="formId">
    <p:selectOneMenu id="type" value="#{testEntity.type}>
        <p:ajax event="change" update=":formId:address"/>
        <f:selectItem itemLabel="E-mail" itemValue="Email"/>
        <f:selectItem itemLabel="Fax" itemValue="Fax"/>
    </p:selectOneMenu>
    <p:inputText id="address" value="#{testEntity.address}">
        <f:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>
    </p:inputText>
    <!-- button to call bean method with testEntity as param -->
</h:form>

It is not working the validator is never active but the ajax call is working since I can see the change value in other fields.

That's unfortunately not possible. The <f:xxx> tags are taghandlers (not UI components) which run during view build time, not during view render time. So if it's disabled during building of the view, it'll always be disabled until the view is recreated (e.g. by new request or a non-null navigation).

You'd need to have a "global" validator which delegates further to the desired validator based on the type attribute.

E.g.

<p:inputText ... validator="#{testEntity.validateAddress}" />

with

public void validateAddress(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    if (type == Email) {
        context.getApplication().createValidator("emailValidator").validate(context, component, value);
    }
}

Update OmniFaces has recently added a new <o:validator> tag which should solve exactly this problem as follows:

<o:validator validatorId="emailValidator" disabled="#{testEntity.type != 'Email'}"/>

See the showcase example here.

Maybe someone is interested in how I solved it thanks to BalusC help.

Pass type component clientId to custom converter.

<f:attribute name="typeComponentId" value=":formId:type"/>

Validator:

public class TestEntity implements Validator
{
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
    { 
        final String typeComponentId = (String)component.getAttributes().get("typeComponentId");

        final UIInput compType = (UIInput)context.getViewRoot().findComponent(typeComponentId);

        if(compType != null)
        {
            final Type type = (Type)compType.getValue();

            if(type == Type.Email)
                new EmailValidator().validate(context, component, value);
        }
    }
}

Edit:

Not working inside a ui:repeat component such as p:datatable.