2013-01-17 16 views
10

Mi è venuto fuori uno strano problema. Ho cercato di isolare il problema in modo seguente è il mio codice semplificato.I campi di input contengono valori precedenti solo se la convalida non è riuscita

public class MyBean { 

    private List<Data> dataList; 
    Data selectedData; 

    public MyBean() { 
    dataList = new ArrayList<Data>(); 
    dataList.add(new Data("John", 16)); 
    dataList.add(new Data("William", 25)); 
    } 

    public List<Data> getDataList() { 
    return dataList; 
    } 

    public void edit(Data data) { 
    selectedData = data; 
    } 
    public void newData() { 
    selectedData = new Data(null, null); 
    } 

    public Data getSelectedData() { 
    return selectedData; 
    } 

    public class Data { 
    String name; 
    Integer age; 
    Data(String name, Integer age) { 
     this.name = name; 
     this.age = age; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public Integer getAge() { 
     return age; 
    } 
    public void setAge(Integer age) { 
     this.age = age; 
    } 
    } 
} 

xhtml:

<rich:modalPanel id="pop"> 
    <h:form> 
    Name: <h:inputText value="#{myBean.selectedData.name}" required="true" id="txtName"/><br/> 
    Age : <h:inputText value="#{myBean.selectedData.age}" required="true" id="txtAge"/> 
    <a4j:commandButton value="Save"/> 
    <a4j:commandButton value="Close" onclick="Richfaces.hideModalPanel('pop');return false;"/> 
    <br/> 
    <rich:message for="txtName"/><br/> 
    <rich:message for="txtAge"/> 
    </h:form>  
</rich:modalPanel> 

<h:form> 
    <rich:dataTable value="#{myBean.dataList}" var="data"> 
    <rich:column>#{data.name}</rich:column> 
    <rich:column> 
     <a4j:commandLink value="Edit" action="#{myBean.edit(data)}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/> 
    </rich:column> 
    </rich:dataTable> 
    <a4j:commandButton value="New" action="#{myBean.newData()}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/> 
</h:form> 

Questo è il percorso di errore:

  1. Caricare la pagina
  2. Fai clic sul link "Modifica" in prima fila (display pop-up)
  3. In popup, deselezionare il campo "Età" e fare clic su "Salva". (Richiesto messaggio visualizzato)
  4. Fare clic su Annulla (senza riempire il campo "Età")
  5. Fare clic sul secondo collegamento.
  6. Ora mostra dati non pertinenti (dati precedenti). - Questo è il problema
  7. Anche se faccio clic sul pulsante "Nuovo" mostra dati errati.

Ciò accade solo se una convalida non è riuscita nel popup.
C'è una soluzione per questo?

+1

So che questo non ti aiuterà a capire il problema, ma non dovresti avere fiducia nel controller (lato server) per cancellare i valori nella vista (la pagina JSF) quando questo può essere fatto con Javascript semplice (questo vale solo nel nuovo ''). –

+0

Grazie per il tuo suggerimento sull'utilizzo di javascript. Ci proverò e ti informerò non appena avrò avuto un tempo. – prageeth

+0

@LuiggiMendoza: ho usato javascript e ho avuto un certo successo. Ma la mia situazione ** reale ** è un po 'complessa e non potrei usare javascript per la mia attuale ** situazione reale **. Tuttavia, la ringrazio molto per il suggerimento e spero di aggiungere la soluzione alternativa di javascript come risposta a questa domanda per l'uso di altre persone quando ho tempo. :) – prageeth

risposta

27

Questo problema è in JSF 2 anche riconosciuto e spiegato in dettaglio nel seguente risposta: How can I populate a text field using PrimeFaces AJAX after validation errors occur? Se si sta utilizzando JSF 2, si potrebbe avere utilizzato OmniFaces' ResetInputAjaxActionListener o primefaces' <p:resetInput> or resetValues="true" per questo.

Al punto, è necessario cancellare lo stato del componente EditableValueHolder quando sta per essere eseguito ajax, ma che non è incluso in ajax-execute. Per cancellare lo stato, in JSF 2 avresti usato il metodo di convenienza resetValue() per questo, ma questo non è disponibile in JSF 1.2 e devi richiamare i 4 metodi individuali , setLocalValueSet(false), setValid(true) per cancellare lo stato.

Per capire quali componenti devono essere resi ajax, ma non sono stati eseguiti ajax, in JSF 2 si sarebbero utilizzati i metodi PartialViewContext per questo, ma questo non è disponibile in JSF 1.2 che non è standardizzato ajax ancora. Avresti bisogno di giocherellare con API API ajax specifiche di RichFaces per capirlo. Non posso dirlo dall'alto, quindi ecco un esempio di kickoff supponendo che tu già conosca i componenti che devono essere cancellati. Immaginate che il modulo nella popup ha id="popForm" e il campo di input nome ha id="nameInput", ecco come si potrebbe cancellarlo all'interno del metodo newData():

UIInput nameInput = (UIInput) context.getViewRoot().findComponent("popForm:nameInput"); 
nameInput.setValue(null); 
nameInput.setSubmittedValue(null); 
nameInput.setLocalValueSet(false); 
nameInput.setValid(true); 
+1

BalusC, apprezzo molto la tua risposta. Mi ha aiutato a risolvere il mio problema. Ho cambiato il mio metodo 'newData()' secondo il tuo esempio e nel mio metodo 'edit (data) 'ho usato' nameInput.setValue (data.getName()); nameInput.setSubmittedValue (data.getName()); nameInput.setLocalValueSet (false); nameInput.setValid (true); '. Funziona bene Potresti spiegare cosa fa il metodo 'setLocalValueSet()'. Grazie ancora. – prageeth

+1

Indica JSF durante la fase di convalida se il componente è già stato validato con successo o meno. 'IsValid()' restituisce anche 'true' se il componente non è stato ancora validato. Solo se la convalida è fallita, restituisce 'false'. 'IsLocalValueSet()' restituisce 'false' se il componente non è stato ancora validato. Ma se è stato validato con successo, allora verrà impostato il valore locale e 'isLocalValueSet()' restituirà 'true'. – BalusC

+0

Ciao BalusC. C'è qualcosa di simile in Faces ADF? Non voglio chiamare resetValue() perché Button e inputTexts risiedono in regioni diverse e inoltre sono in un af: iterator e voglio una soluzione pulita. –

1

fare una cosa su Annulla azione imposta tutti i valori di popup null. ora nel tuo prossimo clic tutti i valori sono impostati come predefiniti.

o al clic imposta tutti i valori precedenti null. e impostare successivamente tutti i rispettivi valori.

0

Ho avuto lo stesso problema. se stai usando Primefaces, la soluzione è semplice come mettere resetValues="true" sul tuo p: commandLink o p: commandButton che carica l'elemento selezionato.

+0

La domanda riguardava JSF1.2 e RichFaces (RichFaces! = PrimeFaces e la versione PrimeFaces con questa funzionalità non supporta JSF 1.2). Inoltre (quasi) era già nella risposta accettata (e ora è completamente) Meglio modificare la domanda spiegata di wel esistente la prossima volta ... Ma grazie per averci ricordato questo dettaglio ... (forse un commento sulla risposta è un'opzione a). – Kukeltje