Mantenga p:diálogo abierto cuando se produzca un error de validación después del envío
Diálogo de ejemplo mínimo:
<p:dialog header="Test Dialog"
widgetVar="testDialog">
<h:form>
<p:inputText value="#{mbean.someValue}"/>
<p:commandButton value="Save"
onsuccess="testDialog.hide()"
actionListener="#{mbean.saveMethod}"/>
</h:form>
</p:dialog>
Lo que quiero poder hacer es que mbean.saveMethod de alguna manera evite que el cuadro de diálogo se cierre si hubo algún problema y solo envíe un mensaje a través de un gruñido. Este es un caso en el que un validador no ayudará porque no hay forma de saber si algún valor es válido hasta que se envíe un guardado a un servidor back-end. Actualmente hago esto usando el atributo visible y lo apunto a un campo booleano en mbean. Eso funciona, pero hace que la interfaz de usuario sea más lenta porque para abrir o abrir el cuadro de diálogo es necesario acceder al servidor.
Se onsuccess
ejecuta si la solicitud ajax fue exitosa (es decir, no hay ningún error de red, excepción no detectada, etc.), no si el método de acción se invocó exitosamente.
Dado un <p:dialog widgetVar="yourWidgetVarName">
, puede eliminarlo onsuccess
y reemplazarlo por PrimeFaces RequestContext#execute()
dentro saveMethod()
:
if (success) {
RequestContext.getCurrentInstance().execute("PF('yourWidgetVarName').hide()");
}
Nota: PF()
se introdujo en PrimeFaces 4.0. En versiones anteriores de PrimeFaces, necesita yourWidgetVarName.hide()
en su lugar.
Si prefiere no saturar el controlador con scripts específicos de vistas, puede usar oncomplete
en su lugar el cual ofrece un args
objeto que tiene una validationFailed
propiedad booleana:
<p:commandButton ...
oncomplete="if (args && !args.validationFailed) PF('yourWidgetVarName').hide()" />
La if (args)
verificación es necesaria porque puede estar ausente cuando ocurre un error de ajax y, por lo tanto, causar un nuevo error de JS cuando intenta salir validationFailed
de él; en &
lugar de &
es obligatorio por el motivo explicado en esta respuesta , refactorice si es necesario a una función JS que invoque como oncomplete="hideDialogOnSuccess(args, 'yourWidgetVarName')"
se muestra en Mantener <p:dialog> abierto cuando la validación haya fallado .
Sin embargo, si no hay ningún error de validación y el método de acción se activa correctamente, y aún desea mantener el cuadro de diálogo abierto debido, por ejemplo, a una excepción en la llamada al método de servicio, entonces puede activar manualmente validationFailed
desde true
dentro el método de acción del bean de respaldo explícitamente. invocando FacesContext#validationFailed()
. P.ej
FacesContext.getCurrentInstance().validationFailed();
Usar el oncomplete
atributo de tu botón de comando y un script realmente simple te ayudará mucho.
Su cuadro de diálogo y botón de comando serían algo similar a esto:
<p:dialog widgetVar="dialog">
<h:form id="dialogView">
<p:commandButton id="saveButton" icon="ui-icon-disk"
value="#{ui['action.save']}"
update=":dataList :dialogView"
actionListener="#{mbean.save()}"
oncomplete="handleDialogSubmit(xhr, status, args)" />
</h:form>
</p:dialog>
Un guión sería algo como esto:
<script type="text/javascript">
function handleDialogSubmit(xhr, status, args) {
if (args.validationFailed) {
dialog.show();
} else {
dialog.hide();
}
}
</script>
Acabo de buscar en Google esta solución . Básicamente, la idea es usar actionListener en lugar de la acción del botón, y en el bean de respaldo agrega un parámetro de devolución de llamada que luego verificará el método oncomplete del botón. Código parcial de muestra:
JSF primero:
<p:commandButton actionListener="#{myBean.doAction}"
oncomplete="if (!args.validationFailed && args.saved) schedulesDialog.hide();" />
Frijol de respaldo:
public void doAction(ActionEvent actionEvent) {
// do your stuff here...
if (ok) {
RequestContext.getCurrentInstance().addCallbackParam("saved", true);
} else {
RequestContext.getCurrentInstance().addCallbackParam("saved", false);
}
}
Espero que esto ayude a alguien :)