JSF 2.0: jak pominąć walidację JSR-303?

Jak pominąć walidację JSR-303 za pomocą JSF, po kliknięciu przycisku?

Trochę długie pytanie, aby wyjaśnić kilka podejść... Rozważmy listę w formie:

<h:form id="form">
    <h:commandButton value="Add row">
        <f:ajax execute="foo" listener="#{bean.add()}" render="foo" />
    </h:commandButton>
    <h:dataTable id="foo" var="foo" value="#{bean.foos}">
        <h:column>
            Name: <h:inputText id="field" value="#{foo.name}" required="true" />
            <h:messages for="field" />
        </h:column>
        <h:column>
            <h:commandButton value="Remove">
                <f:ajax execute=":form:foo" listener="#{bean.remove(foo)}" render=":form:foo" />
            </h:commandButton>
        </h:column>
    </h:dataTable>
</h:form>

Gdy użytkownik kliknie Dodaj lub Usuń wiersz, akcja powinna zostać wykonana bez walidacji. Problem w tym, że JSF ponownie renderuje całą listę i próbuje ją zweryfikować. Jeśli są zmiany wersji roboczej, które nie sprawdzają poprawności, pojawiają się błędy walidacji i metoda listener nigdy nie jest wywoływana (ponieważ uniemożliwia to nieudana Walidacja). Jednak dodanie immediate="true" do F: ajax pozwala na wykonanie metody pomimo błędów walidacji. Jednak błędy walidacji nadal występują i są tutaj pokazywane.

Widzę dwie opcje:

1) Użyj immediate= "true" i nie pokazuj błędów walidacji

Dla przycisków bez walidacji, Ustaw immediate= "true", a dla H: messages do:

<h:messages rendered="#{param['SHOW_VALIDATION']}" />

Następnie Ustaw Save-button (który powinien próbować zapisać formularz), aby wysłać ten parametr:

<h:commandButton>
    <f:param name="SHOW_VALIDATION" value="true" />
</h:commandButton>

To powoduje walidację, ale komunikaty są po prostu nie pokazywane, chyba że występuje parametr SHOW_VALIDATION.

2) zadeklarować walidację w faktach warunkowo:

<h:inputText>
    <f:validateRequired disabled="#{!param['VALIDATE']}" />
</h:inputText>

I przycisk zapisu:

<h:commandButton>
    <f:param name="VALIDATE" value="true" />
</h:commandButton>

Powoduje, że pola są weryfikowane tylko wtedy, gdy występuje parametr VALIDATE (=po naciśnięciu przycisku Zapisz).

/ Align = "left" / Jak mogę po prostu użyć walidacji JSR-303 Bean, ale pominąć ją po zadeklarowaniu?
Author: Tuukka Mustonen, 2011-01-31

4 answers

Ustaw swoje procedury obsługi zdarzeń jako immediate=true i wywołaj FacesContext.renderResponse() przed ich zakończeniem.

UPDATE :

Modyfikacje w formie przykładowej:

<h:form id="form">
    <h:commandButton value="Add row">
        <!-- Added immediate="true" to call bean.add() before validation phase -->
        <f:ajax execute="foo" listener="#{bean.add()}" render="foo" immediate="true"/>
    </h:commandButton>
    <h:dataTable id="foo" var="foo" value="#{bean.foos}">
        <h:column>
            Name: <h:inputText id="field" value="#{foo.name}" required="true" />
            <h:messages for="field" />
        </h:column>
        <h:column>
            <h:commandButton value="Remove">
                <!-- Added immediate="true" to call bean.remove() before validation phase -->
                <f:ajax execute=":form:foo" listener="#{bean.remove(foo)}" render=":form:foo" immediate="true"/>
            </h:commandButton>
        </h:column>
    </h:dataTable>
</h:form>

Modyfikacje w kodzie fasoli:

...
public void add() {
    // Your add() code
    ...
    // Added FacesContext.renderResponse() call to skip to render response phase
    FacesContext.getCurrentInstance().renderResponse();
}
...
public void remove() {
    // Your remove() code
    ...
    // Added FacesContext.renderResponse() call to skip to render response phase
    FacesContext.getCurrentInstance().renderResponse();
}
...
 9
Author: gpeche,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 12:09:42

Możesz wyłączyć walidację bean za pomocą znacznika f: validateBean, który ma atrybut disabled.

Przykład:

<h:inputText value="#{bean.name}">
   <f:validateBean disabled="#{anotherBean.flag}"/>
</h:inputText>
 8
Author: victor herrera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-09 02:22:47

Właśnie opublikowaliśmy rozwiązanie tego problemu. Pełny szczegół znajduje się tutaj: http://www.springfuse.com/2011/12/15/skip-jsf-validation-depending-on-action.html

W skrócie, wykorzystuje atrybut wiążący znacznika validateBean. Pozwala to przechwycić metodę walidacji i zdecydować, na podstawie klikniętego przycisku, czy pozwolić jej przejść, czy nie.

 2
Author: Nicolas Romanetti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-16 14:56:17

Sytuacja: W kodzie strony znajduje się Duży formularz z dużą ilością pól wejściowych. Istnieje kilka przycisków, z których każdy wskazuje na osobną akcję w oddzielnej fasoli.

Rozwiązanie, które zadziałało na mnie...
  1. w kodzie strony: dodaj immediate="true" do przycisku i podaj id pól wejściowych, których chcesz użyć w fasoli.
 <p:inputText id="someHtmlInputId"
               maxlength="30" 
               value="#{beanName.attr}" />


 <p:commandButton id="someHtmlButtonId"
                   actionListener="#{beanName.doStuff}" 
                   value="Button Label"
                   ajax="false"
                   immediate="true"/>
  1. w metodzie bean doStuff get the parameters by the name fragment couse before the input name JSF put some other identyfikatory i wynikowa nazwa parametru mogą wyglądać następująco: someFormId: j_idt54: someHtmlInputId
Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
if (params != null) {
  for (String k: params.keySet())
      if (k.indexOf("someHtmlInputId") != -1)
          params.get(k); // This is Your input parameter value waiting to be processed ;)
}
 -1
Author: ITCuties,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-03 10:01:47