validation - valor - validadores java
JSF omitir Validación obligatoria sin inmediato=verdadero (5)
Cada botón crea una entrada dentro de la lista de parámetros siempre que sea miembro del formulario. Así que simplemente aplique una verificación de la presencia de esa entrada al parámetro "requerido":
<h:form id="form" prependId="true">
...
<p:inputText id="someId"
required="#{param[''form:save'']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>
Cuando hago clic en "Enviar", el param[''form:save'']
es NULL
, que luego convierte la expresión en true
para que se ejecute la validación.
Cuando hago clic en "Guardar", el param[''form:save'']
NOT NULL
(¡pero está vacío!), Que se resuelve en false
por lo que se ignora la validación. (O supongamos que JSF piensa que no es un campo obligatorio debido a que la expresión se evalúa como false
)
Tengo formularios múltiples, donde tengo campos obligatorios y campos opcionales.
Para enviar un formulario de este tipo, requiero la validación en el atributo requerido que se ejecutará, que funciona bien. Para cancelar un formulario de este tipo, utilizo el atributo immediate="true"
en el p:commandbutton
, que hace que su acción suceda durante Apply-Values Request- Phase como se describe aquí: ¿Cómo saltarse la validación cuando se hace clic en un botón específico?
Sin embargo, para formularios grandes, deseo proporcionar al usuario un botón Guardar, para que pueda continuar más tarde.
Por solo guardar el estado actual, también quiero ignorar la validación del atributo requerido. Sin embargo, el uso de immediate="true"
no funciona, porque entonces mi método save simple no guarda nada, porque el ciclo de vida JSF nunca llega a la "UpdateModelValues" -Phase. (De acuerdo con http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html )
Entonces, ¿cómo pasar por alto el cheque requerido pero no saltearse la mitad del ciclo de vida?
En mi caso, no encontré el ID de cliente del botón en los parámetros, pero encontré este param[''javax.faces.source''] = buttonClientId
en el requestmap. El valor será el ID de cliente del botón presionado.
Esta es una excelente pregunta y una respuesta muy útil. Este enfoque ahorra muchas molestias con immediate="true"
.
Me gustaría agregar esta información (pero aún no puedo comentar). Los ejemplos de tu código parecen requerir JSF 2.0 o superior (corrígeme). Si eres como yo condenado a usar JSF 1.1 / 1.2, entonces considera estos cambios / adiciones:
<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param[''save'']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
- No hay atributo prependId en JSF 1.1
- Por lo tanto, en el parámetro [...] solo debe especificar el id del botón
- Está utilizando una sintaxis
="{true and ...}"
que podría ser un error (no#
)? - Como puede ver en su propio historial de edición, la lógica "nula o no nula" no es muy intuitiva :) Por eso me gustó inmediatamente la versión
!empty ...
cuando me encontré con ella.
Una alternativa a lo que otros proponen es usar un BeanValidator
personalizado que validará el formulario si, por ejemplo, hizo clic en el botón con id save. Cualquier otro botón no definido implícitamente para realizar la validación no se validará, solo enviará sus datos disponibles. Encuentre el ejemplo completo agradable y limpio here
si desea omitir la validación al hacer clic en el botón, agregue fácilmente el parámetro al botón donde desea omitirlo. Ejemplo:
<p:commandButton value="button1" action="#{bean.action()}" >
<f:param name="skipValidator" value="true"/>
</p:commandButton>
Luego, en el validador puedes leer este parámetro y si es verdadero, omítalo:
@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{
public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException {
if(!continueValidation()){
return;
}
// validation process
}
protected boolean continueValidation() {
String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
return false;
}
return true;
}
}