2016-10-10 46 views
5

Używam walidatora OmniFaces' <o:validateAll> do sprawdzania poprawności wielu składników wejściowych. Działa to dobrze, o ile nie dodaję go do RichFaces <rich:tabPanel>. Kiedy to zrobię i zostawiam puste pola, sprawdzanie poprawności nie powiedzie się (zgodnie z oczekiwaniami), ale aktywna karta zostanie zmieniona, niezależnie od niepowodzenia sprawdzania poprawności. Inne sprawdzane przeze mnie weryfikatory zapobiegają przełączaniu się tabPanel na inną kartę, gdy walidacja nie powiedzie się.Dlaczego <o: validateAll> zachowuje się inaczej niż inne weryfikatory?

Jaki może być tego powód?

Obecnie używam OmniFaces 2.1 i RichFaces 4.5.17. Finał z Mojarra 2.2.12 na Wildfly 9.0.2.

Oto kod XHTML, aby odtworzyć problem:

<ui:composition xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
       xmlns:f="http://xmlns.jcp.org/jsf/core" 
       xmlns:h="http://xmlns.jcp.org/jsf/html" 
       xmlns:o="http://omnifaces.org/ui" 
       xmlns:rich="http://richfaces.org/rich"> 

    <h:form id="form"> 

     <rich:messages /> 

     <rich:tabPanel id="tabPanel"> 

     <rich:tab id="tab1" header="Tab 1"> 
      <h:inputText id="myDouble" value="#{someDoubleVal}"> 
      <f:validateDoubleRange minimum="1.0" maximum="2.0"/> 
      </h:inputText> 
      <o:validateAll id="allValid" components="myDouble" message="Missing value!" /> 
     </rich:tab> 

     <rich:tab id="tab2" header="Tab 2"> 
      Just another tab to switch. 
     </rich:tab> 

     </rich:tabPanel> 

    </h:form> 

</ui:composition> 

wprowadzić wartość poza 1.0 i 2.0 i spróbuj przełączyć się na kartę 2, aby zobaczyć oczekiwane zachowanie, wywołane przez <f:validateDoubleRange>: wyświetlany jest twarze-wiadomość i pierwsza karta jest nadal aktywna.

Pozostaw puste dane i spróbuj przejść do Tab 2, aby zobaczyć zachowanie <o:validateAll>: sprawdzanie poprawności wydaje się nieudane (wyświetlany jest komunikat o treści), ale aktywna jest karta 2.

Aktualizacja: Opisane zachowanie dotyczy z switchType="ajax" (domyślnie), a także z switchType="server". W obu przypadkach panel-panel wykonuje przesłanie zawartych danych wejściowych, więc z punktu widzenia użytkownika przełączanie tabulatorów wydaje się być takie samo, jak w przypadku przesłania <h:commandButton> (technicznie mogą to być różnice, nie znam szczegóły implementacji panelu zakładki).

Gdybym wykonać zakładkę przełącznik poprzez regularne <h:commandButton> z <f:setPropertyActionListener> The <o:validateAll> zachowuje się tak samo jak innych weryfikatorów, czyli karta-switch nie jest wykonywana z powodu błędu walidacji.

<rich:tabPanel id="tabPanel" activeItem="#{bb.activeTab}"> 
... 
    <rich:tab id="tab1" name="tab1" header="Tab 1"> 
    ... 
    <h:commandButton value="submit"> 
     <f:setPropertyActionListener value="tab2" target="#{bb.activeTab}" /> 
    </h:commandButton> 
    ... 
    </rich:tab> 
</rich:tabPanel> 

Uwaga: Jest to tylko przykład pokazujący minimalistyczna problematycznego zachowania. W moim prawdziwym kodzie nie mam tylko jednego komponentu zatwierdzonego przez <o:validateAll> i faktycznie kojarzę wartości wejściowe z komponentem bean. Obserwowane zachowanie jest dokładnie takie samo.

+0

Właśnie się zorientowałem, zmiana pozycji znacznika '' w kodzie XHTML zmienia zachowanie! Umieść go przed komponentami, które powinny zostać zatwierdzone i działa zgodnie z oczekiwaniami. Czy to pożądane zachowanie lub błąd w OmniFaces? Dokumentacja nie wspomina o tym efekcie. Jakieś pomysły? –

+0

Nie wiem, jak bogate: tabPanel działa pod okładkami, ale zachowanie porządku jest udokumentowane w pierwszym akapicie "ogólnego użycia" http://omnifaces.org/docs/javadoc/2.5/org/omnifaces/component/validator/ValidateMultipleFields. html – BalusC

+0

Zgadza się, zachowanie zamawiania jest udokumentowane. Ale mówi również "_Ten walidator można umieścić w dowolnym miejscu formularza, ale należy pamiętać, że składniki będą sprawdzane w kolejności, w jakiej występują w formularzu." ". Nie wyjaśnia to jednak, dlaczego walidacja powoduje inne zachowanie otaczającego panelu z zakładkami. Ale może jest to dziwny składnik RichFaces. Mam wrażenie, że RichFaces ma więcej takich dziwactw. Może spróbuję przykładu z PrimeFaces i zobaczę jak to działa. –

Odpowiedz

2

Problem jest dwojaki.

Pierwszym problemem jest to, <o:validateAll> nie jawnie wywołać context.renderResponse() gdy walidacja nie powiodło się i pozostawia tę pracę do JSF, które będą w sposób dorozumiany nazwać podczas fazy walidacji, gdy co najmniej jeden składnik wejście znajduje się nieważne po <o:validateAll> prowadzi, lub w inny sposób podczas kolejna faza aktualizacji modelu aktualizacji.

Drugi problem to <rich:tabPanel> zdarzenie przełącznika tabulacji w kolejce do fazy wartości modelu aktualizacji zamiast do fazy uruchamiania invoke. Nie jestem pewien, dlaczego faceci RichFaces tak to zaprojektowali, ale konsekwencją jest to, że zdarzenie przełącznika tabulacji jest tak czy inaczej uruchamiane, nawet jeśli sprawdzanie poprawności zakończy się niepowodzeniem podczas fazy wartości modelu aktualizacji.

Podczas przenoszenia <o:validateAll> przed co najmniej jednego składnika związanego wejściowego, a następnie JSF będzie niejawnie nazywać context.renderResponse() w fazie walidacji i dlatego już całkowicie pominąć etap aktualizacji wartości modelowe i dlatego w kolejce wydarzenie wyłącznik zakładka <rich:tabPanel> nie będzie miał szansę być przywoływany.

Naprawiłem to w OmniFaces 2.6-SNAPSHOT zgodnie z issue 322. Podczas korzystania z OmniFaces 2.6 lub nowszego, nie powinno już być więcej miejsca, gdzie <o:validateAll> jest umieszczony w drzewie, aby uzyskać pożądane zachowanie zdarzenia przełącznika tabulacji <rich:tabPanel>, aby nie było wywoływane.

+0

Dzięki za szczegółową odpowiedź i dzięki za poprawkę w OmniFaces. –

+0

Dzięki za pytanie. – BalusC