2013-04-26 20 views
6

Ho un modulo all'interno di un componente p:dialog inviato tramite AJAX. Il modulo nella finestra di dialogo è tramite un ui:include di un altro .xhtml contenente solo il modulo e i relativi componenti (no, non sono moduli di nidificazione, il dialogo stesso non è in alcun modo). Il bean di supporto della pagina inclusa è 'ViewScoped'.Cancella modulo in p: finestra di dialogo chiusura dopo operazione non riuscita/chiamata di metodo

cose più funzionano bene:

  • sulla convalida di successo, il modulo eseguirà il metodo Save; dopo un salvataggio riuscito, la finestra di dialogo si chiude; l'apertura di un record successivo mostra informazioni sul record corrette dal database.
  • In caso di convalida non riuscita, i valori inviati rimangono e la finestra di dialogo rimane aperta e visualizza gli errori di convalida, fissa i campi non validi e invia nuovamente i risultati in un salvataggio riuscito.

Il problema si presenta quando il action chiamato da p:commandButton non riesce. Nel caso in cui non riesca, la finestra di dialogo rimane aperta e visualizza "Errore salvataggio modifiche" tramite h:messages per l'utente; Inoltre, i valori inviati persistono ancora nei campi di input. Questo va bene (e anche desiderato) mentre il modulo rimane aperto, tuttavia - alla chiusura della finestra di dialogo e alla riapertura, i valori inviati sono ANCORA nei campi di testo. Ciò è negativo perché dà all'utente l'impressione che il salvataggio abbia avuto esito positivo (poiché il componente h:messages è vuoto a causa dell'aggiornamento della finestra di dialogo).

Finora ho provato quanto segue, nessuno dei quali hanno risolto il problema:

  • 1,1) Impostazione della backing bean del modulo incluso per una nuova istanza del fagiolo su finestra di dialogo aperta.
  • 1.2) Poiché ora il bean è una nuova istanza, ripopolo anche l'oggetto indirizzo con i dettagli di un bean di dati.
  • 2.1) Disattivazione del pulsante di chiusura nella finestra di dialogo e aggiunta di un pulsante p:commandButton "Annulla" con un componente p:resetInput in per chiudere la finestra di dialogo/reimpostare il modulo. (la finestra di dialogo si chiude, ma i valori inviati nel modulo persistono).
  • 2.2) Chiamando un metodo da questo p:commandButton che rimuove lo RequestMap per il bean di supporto del modulo incluso.
  • 2.3) Provato con il pulsante impostato su immediate=true e immediate=false.
  • 2.4) Provato con il pulsante impostato su [email protected], una tattica simile che ho utilizzato per chiudere un modulo per garantire che abbia nuovi campi alla riapertura dello .

Si potrebbe pensare tra l'impostazione del bean di supporto a una nuova istanza e il ripopolamento dell'oggetto indirizzo che si vedrebbe in una nuova forma, ma NOPE.

Ecco alcuni dei fonte:

Porzione di mainform.xhtml

<p:dialog id="dlgAddress" 
       header="Address Edit" 
       widgetVar="dialogAddress" 
       dynamic="true" 
       modal="false" 
       closable="false" 
       resizable="false" 
       styleClass="dlgAddress" 
       visible="#{addressform.showDlgAddress}"> 
     <ui:include src="addressform.xhtml"/> 
    </p:dialog> 

AddressForm.xhtml

<h:form id="fDlgAddress"> 
    <div id="addresses-container"> 
     <h:messages id="msgDlgAddress" errorClass="errormsg" infoClass="infomsg1" layout="table"/> 
     <h:panelGrid columns="1" 
        styleClass="pgAddresses" 
        rendered="#{!addressform.address.exists}"> 
      <h:outputText value="No active #{addressform.address.atypCode} address found." 
          styleClass="record-not-exists"/> 
      <h:outputText value="Use the form below to create one."/> 
     </h:panelGrid> 
     <p:panelGrid columns="2" 
        styleClass="pgDlgForm pgAddresses"> 
      <h:outputLabel value="Address Type"/> 
      <h:inputText id="atypCode1" 
         value="#{addressform.address.atypCode}" 
         disabled="true" 
         rendered="#{addressform.address.exists}"/> 
      <h:selectOneMenu id="atypCode2" 
          value="#{addressform.address.atypCode}" 
          rendered="#{!addressform.address.exists}"> 
       <f:selectItems value="#{addressform.atypCodeList}" 
           var="atyp" 
           itemValue="#{atyp}" 
           itemLabel="#{atyp}"/> 
      </h:selectOneMenu> 
      <h:outputLabel value="Street 1" 
          for="street1"/> 
      <h:inputText id="street1" 
         value="#{addressform.address.addressLine1}"/> 
      <h:outputLabel value="Street 2" 
          for="street2"/> 
      <h:inputText id="street2" 
         value="#{addressform.address.addressLine2}"/> 
      <h:outputLabel value="Street 3" 
          for="street3"/> 
      <h:inputText id="street3" 
         value="#{addressform.address.addressLine3}"/> 
      <h:outputLabel value="Street 4" 
          for="street4"/> 
      <h:inputText id="street4" 
         value="#{addressform.address.addressLine4}"/> 
      <h:outputLabel value="City" 
          for="city"/> 
      <h:inputText id="city" 
         value="#{addressform.address.city}" 
         required="true" 
         requiredMessage="Please enter a city."/> 
      <h:outputLabel value="State" 
          for="statCode"/> 
      <h:selectOneMenu id="statCode" 
          value="#{addressform.address.stateCode}"> 
       <f:selectItem itemLabel="Select State/Province" 
           itemValue=""/> 
       <f:selectItems value="#{states.statesList}" 
           var="stat" 
           itemValue="#{stat.statCode}" 
           itemLabel="#{stat.statDesc}"/> 
      </h:selectOneMenu> 
      <h:outputLabel value="Zip Code" 
          for="zipCode"/> 
      <h:inputText id="zipCode" 
         value="#{addressform.address.zip}"/> 
      <h:outputLabel value="Country" 
          for="natnCode"/> 
      <h:selectOneMenu id="natnCode" 
          value="#{addressform.address.nationCode}" 
          required="true" 
          requiredMessage="Please choose a nation."> 
       <f:selectItem itemLabel="Select Country" 
           itemValue=""/> 
       <f:selectItems value="#{nations.nationsList}" 
           var="natn" 
           itemValue="#{natn.natnCode}" 
           itemLabel="#{natn.natnDesc}"/> 
      </h:selectOneMenu> 
      <h:outputLabel value="From Date" 
          for="fromDate"/> 
      <p:calendar id="fromDate" 
         value="#{addressform.address.fromDate}" 
         showButtonPanel="true"/> 
      <h:outputLabel value="To Date" 
          for="toDate"/> 
      <p:calendar id="toDate" 
         value="#{addressform.address.toDate}" 
         showButtonPanel="true"/> 
      <h:outputLabel value="Inactivate" 
          for="inactivateAddress" 
          rendered="#{addressform.address.exists}"/> 
      <h:selectBooleanCheckbox id="inactivateAddress" 
            value="#{addressform.address.inactivate}" 
            rendered="#{addressform.address.exists}"/> 
      <h:outputLabel value="Delete" 
          for="deleteAddress" 
          rendered="#{addressform.address.exists}"/> 
      <h:selectBooleanCheckbox id="deleteAddress" 
            value="#{addressform.address.delete}" 
            rendered="#{addressform.address.exists}"/> 
     </p:panelGrid> 
    </div> 
    <div class="button-container"> 
     <p:commandButton value="Save Changes" 
         action="#{addressform.save}" 
         type="submit" 
         ajax="true" 
         process="@form" 
         update="@form"/> 
     <p:commandButton value="Cancel" 
         process="@this" 
         onclick="dialogAddress.hide();"> 
      <p:resetInput target="fDlgAddress"/> 
     </p:commandButton> 
    </div> 
</h:form> 

Recorddetailsform (backup di fagioli per la forma da cui finestra indirizzo è chiamato)

public void showDlgAddress(){ 
     FacesContext ctx = FacesContext.getCurrentInstance(); 
     ELResolver resolver = ctx.getApplication().getELResolver(); 
     RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails"); 

     //Set addressform backing bean to new instance and load address into it from recordDetails 
     resolver.setValue(ctx.getELContext(), null, "addressform", new Addressform()); 
     Addressform addressform = (Addressform) resolver.getValue(ctx.getELContext(), null, "addressform"); 
     addressform.setAddress(recordDetails.getAddress()); 
    } 

AddressForm (di forma indirizzo supporto di fagioli)

public void save() { 
    FacesContext ctx = FacesContext.getCurrentInstance(); 
    RequestContext rctx = RequestContext.getCurrentInstance(); 
    ELResolver resolver = ctx.getApplication().getELResolver(); 
    Records records = (Records) resolver.getValue(ctx.getELContext(), null, "records"); 
    RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails"); 
    Mainform mainform = (Mainform) resolver.getValue(ctx.getELContext(), null, "mainform"); 
    Person person = (Person) resolver.getValue(ctx.getELContext(), null, "person"); 

    //Pretty lengthy SQL stuff here. Commented out. Just wanted to display the display logic below for the dialog. 

    if (errorMsg != null) {//If errorMsg is not null, then error occurred. 
     showDlgAddress = true;//Ensures address dialog remains open in event of action error. 
     queueErrorMessage(errorMsg); 
     rctx.update("dlgAddress"); 
     return;//break out of method on error. 
    } else { 
     showDlgAddress = false; 
     rctx.update("dlgAddress"); 
    } 

    //If everything saves without error, repopulate address and update recordDetails dialog. 
    recordDetails.populateAddress(records.getSelectedRecord()); 
    mainform.updateDlgRecordDetails(); 
} 

Altro Info:

  • JSF2
  • primefaces 3,5
  • Tomcat 6.0
  • Netbeans

risposta

13

Prova questo:

  1. Metti la tua finestra all'interno di un modulo (dialogInputForm)

  2. Add l'attri aggiornamento Bute = ": dialogInputForm"

  3. Nest il tag resetInput all'interno del pulsante che apre la finestra di dialogo e specificare la destinazione come la forma appena creato

sul pulsante di comando:

<p:commandButton process="@this" actionListener="#{bean.prepare}" update=":dialogInputForm" oncomplete="thirdPartyDialog.show()" value="Open Input Dialog" > 
    <p:resetInput target=":dialogInputForm" /> 
</p:commandButton> 

E la forma che contiene la finestra di dialogo

<h:form id="dialogInputForm" > 
... your dialog ... 
</h:form> 
+0

Hmmm ... Posso provare questo al lavoro domani, ma penso di aver già provato questo. Il risultato è stato il p: resetInput ha causato la visualizzazione del modulo come se non fosse stato caricato alcun record, eliminando non solo i valori "bloccati" inviati dal record precedente per cancellare, ma anche i valori del nuovo record in entrata. – mousouchop

+0

Incredibilmente questa soluzione funziona! Ero disperato per questo problema di reimpostare i valori dei miei dialoghi. '' fa il trucco. Molte grazie! –

+1

Sì. Ho trovato che funziona in modo affidabile. Tuttavia, annullo le mie forme all'interno della mia finestra di dialogo, che non sembra causare problemi. Penso che il mio problema sia arrivato quando ho inizialmente provato a usare '@ form' come destinazione per' '. È ** DEVE ** utilizzare un ID modulo effettivo in questo componente e aggiornare anche la stessa forma del tuo esempio precedente. Grazie. – mousouchop

Problemi correlati