Mantenga p: cuadro de diálogo abierto cuando se produce un error de validación después de enviar

Cuadro de diálogo de ejemplo mínimo

Lo que quiero poder hacer es hacer que mbean.saveMethod de alguna manera evite que el diálogo se cierre si hubo algún problema y solo muestra un mensaje a través de gruñido. Este es un caso en el que un validador no será de ayuda porque no hay forma de saber si algún valor es válido hasta que se envíe un archivo guardado a un servidor de fondo. Actualmente hago esto usando el atributo visible y lo señalo a un campo booleano en mbean. Eso funciona pero hace que la interfaz de usuario sea más lenta porque para abrir o cerrar el diálogo se debe presionar el servidor.

El onsuccess ejecuta si la solicitud ajax fue exitosa (es decir, no hay error de red, excepción no detectada, etc.), no si el método de acción fue invocado con éxito.

Dado un Usted podría eliminar el onsuccess y reemplazarlo por PrimeFaces RequestContext#execute() dentro de saveMethod() :

 if (success) { RequestContext.getCurrentInstance().execute("PF('testDialog').hide()"); } 

Nota: PF() se introdujo en PrimeFaces 4.0. En las versiones anteriores de PrimeFaces, necesita testDialog.hide() lugar.

Si prefiere no saturar el controlador con scripts específicos de la vista, puede usar oncomplete en oncomplete lugar, que ofrece un objeto args que tiene una propiedad boolean validationFailed :

  

La verificación if (args) es necesaria porque puede estar ausente cuando se ha producido un error ajax y, por lo tanto, causar un nuevo error JS cuando intenta obtener la validationFailed de él; el & en lugar de & es obligatorio por el motivo explicado en esta respuesta , refactor si es necesario a una función JS que invoca como oncomplete="hideDialogOnSuccess(args, testDialog)" como se muestra en Mantener abierto cuando la validación ha fallado .

Esta última solución (con una pequeña reescritura) debería funcionar para h:commandButton en combinación con un f:ajax


Es lamentable que PrimeFaces no sea compatible con lo que RichFaces ya admite: reevaluación en tiempo de solicitud de EL en los atributos on* . De lo contrario, también podrías hacer esto:

  

Acabo de buscar en Google esta solución . Básicamente, la idea es usar actionListener en lugar de acción de botón, y en backing bean agrega el parámetro de callback que luego se comprobará en el método oncomplete del botón. Ejemplo de código parcial:

JSF primero:

  

Backing Bean:

 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 🙂

Usar el atributo oncomplete desde el botón de comando y el guión realmente simple te ayudará mucho.

Su cuadro de diálogo y botón de comando sería algo similar a esto:

      

Un script sería algo como esto:

  

Yo uso esta solución:

Código JSF:

  ...   

Código del bean de respaldo:

 public void saveTable() { RequestContext rc = RequestContext.getCurrentInstance(); rc.execute("PF('dlgModify').hide()"); } 

Creo que esta es la solución más limpia. Al hacer esto , no necesita cambiar el código de sus botones . Esta solución anula el prototipo de la función hide.

 $(document).ready(function() { PrimeFaces.widget.Dialog.prototype.originalHide = PrimeFaces.widget.Dialog.prototype.hide; // keep a reference to the original hide() PrimeFaces.widget.Dialog.prototype.hide = function() { var ajaxResponseArgs = arguments.callee.caller.arguments[2]; // accesses oncomplete arguments if (ajaxResponseArgs && ajaxResponseArgs.validationFailed) { return; // on validation error, prevent closing } this.originalHide(); }; }); 

De esta manera, puedes mantener tu código como:

  

La solución más fácil es no tener ningún “widget.hide”, ni en onclick, ni en oncomplete. Eliminar las funciones de ocultar y simplemente poner

 visible="#{facesContext.validationFailed}" 

para la etiqueta de diálogo