Свяжите компоненты с представлением, создайте <h:inputHidden value="true">
, который вы помещаете перед компонентами, к которым вы присоединяете валидатор, и передаете компоненты как атрибуты.
Например,
<h:inputHidden value="true" requiredMessage="Please fill in at least one of those fields">
<f:validator validatorId="oneOrMoreValidator" />
<f:attribute name="component1" value="#{component1}" />
<f:attribute name="component2" value="#{component2}" />
</h:inputHidden>
<h:inputText binding="#{component1}" ... />
<h:inputText binding="#{component2}" ... />
с этой реализацией @FacesValidator("oneOrMoreValidator")
:
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
List<UIInput> inputs = new ArrayList<UIInput>();
boolean hasValue = false;
for (int i = 1; i < Integer.MAX_VALUE; i++) {
UIInput input = (UIInput) component.getAttributes().get("component" + i);
if (input != null) {
inputs.add(input);
if (!hasValue) {
Object submittedValue = input.getSubmittedValue();
hasValue |= (submittedValue != null && !String.valueOf(submittedValue).isEmpty());
}
} else {
break;
}
}
if (!inputs.isEmpty() && !hasValue) {
for (UIInput input : inputs) {
input.setValid(false);
}
String requiredMessage = (String) component.getAttributes().get("requiredMessage");
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, requiredMessage, null));
}
}