2013-01-17 6 views
10

Wpadłem na dziwny problem. Próbowałem wyizolować problem, więc poniżej jest mój uproszczony kod.Pola wejściowe zawierają poprzednie wartości tylko w przypadku niepowodzenia sprawdzania poprawności

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> 

To jest ścieżka do błędu:

  1. załadować stronę
  2. Kliknij link "Edytuj" w pierwszym rzędzie (wyświetla popup)
  3. W wyskakującym okienku wyczyść pole "Wiek" i kliknij "Zapisz". (Wymagane wyświetlony komunikat)
  4. Anuluj kliknięcie (bez wypełniania pola "Wiek")
  5. Kliknij drugi link.
  6. Teraz pokazuje nieistotne dane (poprzednie dane). - To jest problem
  7. Nawet po kliknięciu przycisku "Nowy" wyświetla niepoprawne dane.

Dzieje się tak tylko wtedy, gdy sprawdzanie poprawności nie powiedzie się w popupie.
Czy istnieje rozwiązanie tego problemu?

+1

Wiem, że to nie pomoże ci zrozumieć problemu, ale nie powinieneś ufać kontrolerowi (stronie serwera), aby wyczyścić wartości w widoku (stronie JSF), gdy można to zrobić za pomocą zwykłego kodu JavaScript (odnosi się to wyłącznie do nowego ''). –

+0

Dziękujemy za sugestie dotyczące używania javascript. Spróbuję i poinformuję cię, gdy tylko znajdę czas. – prageeth

+0

@ LuiggiMendoza: Użyłem javascript i odniosłem pewien sukces. Ale moja ** prawdziwa ** sytuacja jest trochę skomplikowana i nie mogłem użyć javascript dla mojej obecnej ** prawdziwej sytuacji **. Jednak bardzo dziękuję za podpowiedź i mam nadzieję, że dodam obejście javascript jako odpowiedź na to pytanie dla innych ludzi, kiedy mam czas. :) – prageeth

Odpowiedz

27

Ten problem jest w JSF 2 również rozpoznawane i szczegółowo wyjaśnione w poniższym odpowiedź: How can I populate a text field using PrimeFaces AJAX after validation errors occur? Jeśli uzywasz JSF 2, mogłeś używane OmniFaces' ResetInputAjaxActionListener lub PrimeFaces' <p:resetInput> or resetValues="true" do tego.

Do tego punktu należy wyczyścić stan komponentu EditableValueHolder, gdy ma zostać renderowany przez ajax, ale który nie jest zawarty w elemencie ajax-execute. Aby wyczyścić stan, w JSF 2 użyłbyś do tego metody wygody: resetValue(), ale nie jest to możliwe w JSF 1.2 i musisz wywołać 4 indywidualne metody, aby usunąć stan.

Aby dowiedzieć się, które elementy mają być ajax-renderowane, ale nie było ajax-wykonywany w JSF 2 byś stosowane PartialViewContext metody, ale to nie jest dostępne w JSF 1.2, która nie została znormalizowana jeszcze ajax. Aby to zrozumieć, trzeba poradzić sobie z konkretnym API ajaxowym RichFaces. Nie mogę tego powiedzieć z góry, więc oto przykład kickoff zakładający, że już znasz składniki, które muszą zostać wyczyszczone. Wyobraźmy sobie, że forma w popup ma id="popForm" i polu Nazwa ma id="nameInput", oto jak można wyczyścić go wewnątrz metody newData():

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

BalusC, naprawdę doceniam twoją odpowiedź. Pomógł mi rozwiązać mój problem. Zmieniłem metodę 'newData()' zgodnie z twoim przykładem iw mojej metodzie 'edit (data)' użyłem 'nameInput.setValue (data.getName()); nameInput.setSubmittedValue (data.getName()); nameInput.setLocalValueSet (false); nameInput.setValid (true); '. To działa dobrze. Czy mógłbyś wyjaśnić, co robi metoda 'setLocalValueSet()'. Dzięki jeszcze raz. – prageeth

+1

Wskazuje JSF podczas fazy sprawdzania poprawności, jeśli składnik został już pomyślnie sprawdzony, czy nie. Wartość 'isValid()' zwraca także wartość "true", jeśli składnik nie został jeszcze sprawdzony. Tylko wtedy, gdy sprawdzanie poprawności nie powiodło się, zwraca 'false'. 'IsLocalValueSet()' zwraca 'fałsz', jeśli komponent nie został jeszcze sprawdzony. Ale jeśli zostanie pomyślnie sprawdzona, wówczas zostanie ustawiona wartość lokalna, a 'isLocalValueSet()' zwróci wartość "true". – BalusC

+0

Witaj BalusC. Czy jest coś podobnego w twarzach ADF? Nie chcę wywoływać metody resetValue(), ponieważ Button i inputTexts znajdują się w różnych regionach, a także w af: iterator i chcę mieć czyste rozwiązanie. –

1

wykonaj jedną czynność podczas anulowania ustaw wszystkie wartości wyskakujące puste. teraz w następnym kliknięciu wszystkie wartości ustawione jako domyślne.

lub po kliknięciu ustaw wszystkie poprzednie wartości null. i ustaw później wszystkie odpowiednie wartości.

0

miałem ten sam problem. jeśli używasz Primefaces, rozwiązanie jest tak proste jak umieszczenie resetValues="true" na twoim p: commandLink lub p: commandButton, który ładuje wybrany element.

+0

Pytanie dotyczyło JSF1.2 i RichFaces (RichFaces! = PrimeFaces i wersja PrimeFaces, która ma tę funkcję, nie obsługuje JSF 1.2). Poza tym (prawie) był już w zaakceptowanej odpowiedzi (a teraz jest w pełni) Lepiej edytować przyszłe, już istniejące, wyjaśnione pytanie ... Ale dzięki za przypomnienie nam o tym szczególe ... (może komentarz do odpowiedzi jest opcją do). – Kukeltje

Powiązane problemy