Introduction
I encountered a situation the other day where I need to include a JSF page based on a parameter passed in via a<f:viewParam>
. This seems like a very reasonable kind of idea. I expected to be able to make the <ui:include/>
use a dynamically set src
parameter using EL from the <f:viewParam>
. This is where I went wrong (the idea was good...). The <ui:include/>
is a tag handler. It is evaluated on Restore View Phase. The value processing does not take place until the Apply Request Values Phase. This presents a problem since the EL binding for my <ui:include/>
is based on the <f:viewParam>
which is a UIInput
object. So we are out of phase. The page will display the results, but all the AJAX will not work.
A Solution
A solution to the problem involves using static<ui:include/>
elements wrapped in <ui:fragment/>
elements. This allows the tag handler to resolve the page to include, and then the fragment determines (via late binding) whether to display the page based on the <f:viewParam>
passed. The page is supported by a @ViewScoped
bean to keep the page in scope.
Code
Here is an example of how to do it.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <? xml version = '1.0' encoding = 'UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> > < h:head > < title >Index</ title > < f:metadata > < f:viewParam name = "page" value = "#{index.page}" /> </ f:metadata > </ h:head > < h:body > < p > These examples use static binding on the < ui:include /> and use the the < ui:fragment /> < code >rendered</ code > attribute to determine which page to display. Since these elements are evaluated after the component tree is restored, the AJAX will work. </ p > < ui:fragment rendered = "#{index.page eq 'page1'}" > < ui:include src = "page1.xhtml" /> </ ui:fragment > < ui:fragment rendered = "#{index.page eq 'page2'}" > < ui:include src = "page2.xhtml" /> </ ui:fragment > < h:button id = "button1" value = "Page 1" outcome = "good.xhtml?page=page1" includeViewParams = "true" /> < h:button id = "button2" value = "Page 2" outcome = "good.xhtml?page=page2" includeViewParams = "true" /> < h:button outcome = "index" value = "Home" /> </ h:body > </ html > |
0 comments :
Post a Comment