JSF skip Required-Validation without immediate=true

Mam wiele formularzy, gdzie mam pola obowiązkowe i pola opcjonalne.

To submit taki formularz wymagam walidacji na wymaganym atrybucie do wykonania, co działa dobrze. Aby anulować takiego formularza używam atrybutu {[0] } na p:commandbutton, co sprawia, że jego akcja dzieje się podczas Apply request Values-Phase tak jak tutaj: Jak pominąć walidację po kliknięciu określonego przycisku?

Jednak dla dużych form chcę podaj użytkownikowi przycisk Zapisz, aby mógł kontynuować później.

Do zapisywania bieżącego stanu chcę również zignorować walidację wymaganego atrybutu. Jednak używanie immediate="true" nie działa, ponieważ wtedy moja metoda save simple nic nie zapisuje, ponieważ cykl życia JSF nigdy nie trafia w fazę "UpdateModelValues". (Acording to http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html )

Więc, jak ominąć wymagane-sprawdź, ale nie pominąć połowę cykl życia?

Author: Community, 2013-01-15

5 answers

Każdy przycisk tworzy wpis wewnątrz Param-listy tak długo, jak jest członkiem formularza. Więc po prostu zastosowałem sprawdzanie obecności tego wpisu do parametru "required":

<h:form id="form" prependId="true">
...
<p:inputText id="someId"
    required="#{param['form:save']==null}" ... />
...
<p:commandButton id="save" value="Save" />
<p:commandButton id="submit" value="Submit" />
<p:commandButton id="cancel" value="Cancel" immediate="true" />
</h:form>

Po kliknięciu "Submit" param['form:save'] jest NULL, które następnie zmienia wyrażenie na true, więc Walidacja jest wykonywana.

Po kliknięciu " Zapisz "param['form:save'] jest NOT NULL (ale puste!), która rozwiązuje się na false, więc Walidacja jest ignorowana. (Albo powiedzmy, że JSF uważa, że nie jest to pole wymagane ze względu na expression beeing evaluated to false)

 56
Author: dognose,
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
2015-08-11 15:17:33

Jeśli chcesz pominąć walidację po kliknięciu przycisku, łatwo dodaj parametr do przycisku, w którym chcesz go pominąć. Przykład:

<p:commandButton value="button1" action="#{bean.action()}" >
   <f:param name="skipValidator" value="true"/>
</p:commandButton>

Następnie w walidatorze można odczytać ten parametr i jeśli jest on prawdziwy to pomiń go:

@FacesValidator("com.validators.MyValidator")
public class MyValidator implements Validator{

  public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException { 
    if(!continueValidation()){
      return;
    }
    // validation process
  }

protected boolean continueValidation() {
    String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
    if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
      return false;
    }
    return true;
  } 
}
 4
Author: Juraj,
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
2015-02-12 08:41:56

To doskonałe pytanie i bardzo pomocna odpowiedź. Takie podejście oszczędza wiele kłopotów z immediate="true".

Chciałbym dodać tę informację (ale nie mogę jeszcze komentować). Twoje przykłady kodu wydają się wymagać JSF 2.0 lub wyższego (popraw mnie). Jeśli tak jak ja używasz JSF 1.1/1.2 to rozważ te zmiany/dodatki:

<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
  • nie ma atrybutu prependId w JSF 1.1
  • dlatego w param[...] musisz tylko podać przycisk id
  • używasz składni ="{true and ...}", która może być błędem (nie #)?
  • jak widać z własnej historii edycji logika "null or not null" nie jest zbyt intuicyjna:) dlatego od razu spodobała mi się wersja !empty ..., Kiedy się na nią natknąłem.
 3
Author: SebastianH,
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
2014-01-30 11:25:26

W moim przypadku nie znalazłem clientId przycisku w params ale znalazłem to param['javax.faces.source'] = buttonClientId w requestmap. Wartość będzie clientId klikniętego przycisku.

 0
Author: Shady Aziz,
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
2014-12-22 15:29:04

Alternatywą dla tego, co inni zaproponowali, jest użycie niestandardowego BeanValidator, który potwierdzi formularz, jeśli powiedzmy, kliknie przycisk z id Zapisz. Każdy inny przycisk, który nie jest domyślnie zdefiniowany do przeprowadzenia walidacji, nie potwierdzi, ale po prostu prześle dostępne dane. Pełny przykład znajdziesz tutaj

 0
Author: Given Nyauyanga,
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
2016-05-03 12:52:36