Mantieni la finestra di dialogo p: aperta quando si verifica un errore di convalida dopo l’invio

Finestra di dialogo di esempio minima:

Quello che voglio essere in grado di fare è che mbean.saveMethod impedisca in qualche modo la chiusura della finestra di dialogo in caso di problemi e produca solo un messaggio attraverso il ringhio. Questo è un caso in cui un validatore non sarà d’aiuto perché non c’è modo di dire se qualche valore è valido fino a quando un salvataggio non viene inviato ad un server back-end. Attualmente lo faccio usando l’attributo visible e lo indirizza a un campo booleano in mbean. Funziona, ma rende l’interfaccia utente più lenta perché l’apertura o la chiusura della finestra di dialogo richiede di colpire il server.

L’ onsuccess viene eseguito se la richiesta ajax ha avuto esito positivo (ovvero non vi sono errori di rete, eccezione non rilevata, ecc.), Non se il metodo di azione è stato richiamato correttamente.

Dato un Puoi rimuovere il onsuccess e sostituirlo con PrimeFaces RequestContext#execute() all’interno di saveMethod() :

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

Nota: PF() stato introdotto in PrimeFaces 4.0. Nelle versioni precedenti di PrimeFaces, è necessario invece testDialog.hide() .

Se si preferisce non ingombrare il controller con script specifici della vista, è ansible utilizzare invece oncomplete che offre un object args che ha una proprietà boolean validationFailed :

  

Il controllo if (args) è necessario perché potrebbe essere assente quando si è verificato un errore Ajax e quindi causare un nuovo errore JS quando si tenta di ottenere validationFailed da esso; il & invece di & è obbligatorio per il motivo spiegato in questa risposta , refact se necessario a una funzione JS che invochi come oncomplete="hideDialogOnSuccess(args, testDialog)" come mostrato in Keep aperto quando la convalida non è riuscita .

Quest’ultima soluzione (con una piccola riscrittura) dovrebbe funzionare per plain jsf h:commandButton in combinazione con f:ajax


È sfortunato che PrimeFaces non supporti ciò che RichFaces già supporta: rivalutazione richiesta-tempo degli attributi EL in on* . Potresti anche essere in grado di fare proprio questo:

  

Ho cercato su Google questa soluzione . Fondamentalmente l’idea è di usare actionListener invece dell’azione del pulsante, e nel bean backing si aggiunge il parametro callback che sarà quindi il check-in del metodo oncomplete del pulsante. Esempio di codice parziale:

JSF prima:

  

Fagiolo di supporto:

 public void doAction(ActionEvent actionEvent) { // do your stuff here... if (ok) { RequestContext.getCurrentInstance().addCallbackParam("saved", true); } else { RequestContext.getCurrentInstance().addCallbackParam("saved", false); } } 

Spero che questo aiuti qualcuno 🙂

L’ oncomplete dell’attributo oncomplete dal tuo pulsante di comando e di uno script davvero semplice ti aiuterà molto.

La tua finestra di dialogo e il pulsante di comando sarebbero qualcosa di simile a questo:

      

Uno script dovrebbe essere qualcosa del genere:

  

Io uso questa soluzione:

Codice JSF:

  ...   

Backing bean code:

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

Credo che questa sia la soluzione più pulita. In questo modo non è necessario modificare il codice dei pulsanti . Questa soluzione sovrascrive il prototipo della funzione 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(); }; }); 

In questo modo, puoi mantenere il tuo codice come:

  

La soluzione più semplice è non avere alcun “widget.hide”, né in onclick, né in oncomplete. Rimuovi le funzioni Nascondi e metti

 visible="#{facesContext.validationFailed}" 

per il tag di dialogo