validation - valor - validadores java
JSF no es compatible con la validación de campo cruzado, ¿hay alguna solución? (2)
JSF 2.0 solo le permite validar la entrada en un campo, como comprobar para ver si es una cierta longitud. No le permite tener un formulario que diga "ingresar ciudad y estado, o ingresar solo un código postal".
¿Cómo has conseguido esto? Solo me interesan las respuestas que involucren la fase de validación de JSF. No estoy interesado en poner la lógica de validación en Managed Beans.
Apache ExtVal no fue mencionado aquí.
Hay algunas validaciones cruzadas (entre otras validaciones que pueden ser útiles):
El enfoque personalizado más fácil que he visto y usado hasta ahora es crear un campo <h:inputHidden>
con un <f:validator>
en el que se hace referencia a todos los componentes involucrados como <f:attribute>
. Si lo declara antes de los componentes a ser validados, puede obtener los valores enviados dentro del validador mediante UIInput#getSubmittedValue()
.
P.ej
<h:form>
<h:inputHidden id="foo" value="true">
<f:validator validatorId="fooValidator" />
<f:attribute name="input1" value="#{input1}" />
<f:attribute name="input2" value="#{input2}" />
<f:attribute name="input3" value="#{input3}" />
</h:inputHidden>
<h:inputText binding="#{input1}" value="#{bean.input1}" />
<h:inputText binding="#{input2}" value="#{bean.input2}" />
<h:inputText binding="#{input3}" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
(tenga en cuenta el value="true"
en la entrada oculta, el valor real en realidad no importa, pero tenga en cuenta que el validador no se activará necesariamente cuando sea nulo o esté vacío, dependiendo de la versión y configuración de JSF)
con
@FacesValidator(value="fooValidator")
public class FooValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
UIInput input1 = (UIInput) component.getAttributes().get("input1");
UIInput input2 = (UIInput) component.getAttributes().get("input2");
UIInput input3 = (UIInput) component.getAttributes().get("input3");
// ...
Object value1 = input1.getSubmittedValue();
Object value2 = input2.getSubmittedValue();
Object value3 = input3.getSubmittedValue();
// ...
}
}
Si declara <h:inputHidden>
después de los componentes a ser validados, los valores de los componentes involucrados ya están convertidos y validados y debe obtenerlos mediante UIInput#getValue()
o quizás UIInput#getLocalValue()
(en caso el UIInput
no es isValid()
) en su lugar.
Ver también:
Alternativamente, puede usar etiquetas / componentes de terceros para eso. RichFaces, por ejemplo, tiene una etiqueta <rich:graphValidator>
para esto, Seam3 tiene un <s:validateForm>
para esto, y OmniFaces tiene varios componentes estándar <o:validateXxx>
para esto, que se muestran here . OmniFaces utiliza un enfoque basado en componentes mediante el cual el trabajo se realiza en UIComponent#processValidators()
. También permite customizing de tal manera que lo anterior se puede lograr de la siguiente manera:
<h:form>
<o:validateMultiple id="foo" components="input1 input2 input3" validator="#{fooValidator}" />
<h:inputText id="input1" value="#{bean.input1}" />
<h:inputText id="input2" value="#{bean.input2}" />
<h:inputText id="input3" value="#{bean.input3}" />
<h:commandButton value="submit" action="#{bean.submit}" />
<h:message for="foo" />
</h:form>
con
@ManagedBean
@RequestScoped
public class FooValidator implements MultiFieldValidator {
@Override
public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
// ...
}
}
La única diferencia es que devuelve un valor boolean
y que el mensaje debe especificarse como atributo de message
en <o:validateMultiple>
.