Během zpracování událostí v životním cyklu mohou být volány některé metody třídy
FacesContext
, které přeruší či zkrátí cyklus.
Přerušení může nastat voláním metody responseComplete()
, která se
použije v případě, že požadavek byl přesměrován na jiný zdroj a JSF se již nemusí o
odpověď starat. Může se jednat např. o situaci, kdy je uživatel přesměrován na
obyčejnou HTML stránku bez JSF elementů, či na soubor, který má být stažen atp. Tato
možnost je na obrázku 7.2 znázorněna šipkami s popiskem
"Response Complete".
Zkrácení životního cyklu lze provést metodou renderResponse()
, kterou
byla zmíněna již výše v souvislosti s Initial
Requestem. Metoda zajistí násilné přeskočení zbývajících fází a
přikročí rovnou k fázi Render Response. Tato
možnost je na obrázku 7.2 znázorněna šipkami s popiskem
"Render Response". Zkrácení cyklu se používá
například v souvislosti s atributem immediate
, který jsem zmínil v
sekci 4.3.1 – „Základní atributy tagů“.
Za normálních okolností jsou akce typu value-changed
events zpracovávány ve fázi Process
Validations a akce typu action
events ve fázi Invoke
Application, což je většinou žádoucí chování [3]. Někdy však můžeme potřebovat validaci uspíšit, nebo
přeskočit a k tomu slouží právě atribut immediate
, který dokáže
ovlivnit, v jaké fázi budou akce zpracovávány. Můžeme ho použít buď u
UIInput
, nebo u UICommand
komponent.
Může nastat situace, kdy potřebujete konverzi a validaci přeskočit.
Představte si například formulář, kde máte jedno pole s atributem
required
nastaveným na hodnotu true a na konci formuláře je kromě tlačítka Potvrdit také tlačítko Zrušit, které uživatele vrací třeba na předchozí stránku.
Pokud by chtěl uživatel využít tlačítko Zrušit, nemá smysl vyžadovat po něm vyplnění povinných
polí.
Pro tento případ se nám hodí atribut immediate
. Nastavení
tohoto atributu na hodnotu true zajistí,
že akce vyvolaná tlačítkem bude zpracována již po fázi Apply Request Values. Hned nato je zpracována
akce, která řídí navigaci a automaticky volá metodu
renderResponse()
. Zpracování události tak proběhne ještě
před procesy konverze a validace a uživatel bude bez problémů přesměrován na
požadovanou stránku.
Příklad 7.1. Využití atributu immediate
u
UICommand
komponenty
<h:inputText id="vek" value="#{objednavka.cena}" required="true"/><br/> <h:commandButton value="Potvrdit" action="success"/> <h:commandButton value="Zrušit" action="cancel" immediate="true"/>
Nyní si vzpomeňte na příklad
6.5, kde jsme měli combobox s atributem onchange
, jenž volal
metodu submit()
. Tato metoda na straně klienta zajišťuje
potvrzení formuláře ihned po změně hodnoty. Představte si, že součástí
formuláře je také povinné textové pole, jehož vyplnění však chcete
kontrolovat, jen pokud je stisknuto potvrzovací tlačítko, nikoli při změně
hodnoty comboboxu.
V tom případě nastavíte tagu comboboxu
atribut immediate
na true,
čímž zajistíte, že jeho konverze a validace proběhne již ve fázi Apply Request Values a hned nato bude vyhozena
událost value-changed event. Situace je
zde však o něco složitější, než u UICommand
komponenty. Zde totiž není volána metoda renderResponse()
automaticky a za normálních okolností by následně proběhla konverze a
validace všech ostatních polí. Pokud se tomu chcete vyhnout, musíte zavolat
metodu renderResponse()
sami ve vašem listeneru.
Příklad 7.2. Využití atributu immediate
u
UIInput
komponenty
<h:selectOneMenu value="#{objednavka.mena}" onchange="submit()" immediate="true"> <f:valueChangeListener type="beany.zmenaMeny"/> <f:selectItems value="#{objednavka.meny}"/> </h:selectOneMenu>
Do listeneru byste pak museli přidat
volání metody renderResponse()
-
FacesContext.getCurrentInstance().renderResponse();
(pro
více informací o třídě FacesContext
a jejich metodách
viz [6]).