I have the following page:
<h:form id="gameSelectionForm">
<h:selectOneMenu id="gameSelection">
<f:selectItems value="#{gameBean.gameIds}" />
</h:selectOneMenu>
<h:commandButton id="gameSelector" value="Play" action="#{gameBean.changeGame}" />
</h:form>
<h:panelGroup id="gameDiv">
<f:verbatim>
<iframe src="/levelup/resources/games/#{gameBean.gameId}/#{gameBean.htmlPage}" width="700px" height="800px" frameborder="0"/>
</f:verbatim>
</h:panelGroup>
When I click on the "gameSelector" button, here is the sequence of events:
1. gameBean.getGameId and gameBean.getHtmlPage are called
2. gameBean.changeGame is called
3. The page is refreshed.
My issues lies in the order of 1. and 2. The changeGame modifies a gameBean variable that is used by the getGameId and getHtmlPage. I thus want to it execute first, so that when other panels are refreshed, they contain the proper data.
Please note that this issue seems to occur only for the call within the gameDiv element (other variables are properly refreshed).
Would you have any idea as to what I could do to revert the order of 1. and 2., so that the changeGame() method is the first one called?
I am using JavaServer Faces 2.0 on Tomcat 7.0.
Thanks in advance
As per your own answer on this topic:
I removed the f:verbatim tag, and now it works properly. I still don't understand why it has caused this behaviour though.
The <f:verbatim>
was introduced in JSF 1.0 a long time back with the sole purpose to be able to include plain HTML in the JSF component tree. On JSF 1.0 (and 1.1), when the component tree get built, all the plain HTML was ignored. The page get rendered with all the plain HTML first and then the rendered HTML of JSF components thereafter. So for example
<p>Hello</p>
<h:inputText />
<p>World</p>
<h:outputText value="outputtext" />
<p>This is weird</p>
get rendered as
<p>Hello</p>
<p>World</p>
<p>This is weird</p>
<input type="text" />
outputtext
The <f:verbatim>
allowed developers to take plain HTML into the JSF component tree, so that they get rendered "in sync" as you'd expect from the coding.
<f:verbatim><p>Hello</p></f:verbatim>
<h:inputText />
<f:verbatim><p>World</p></f:verbatim>
<h:outputText value="outputtext" />
<f:verbatim><p>This is weird</p></f:verbatim>
They however get inlined during view build time, not during view render time. This is the cause of your problem, the getters get invoked during restore view phase instead of render response phase.
Since JSF 1.2, with the improved view handler, it was possible to inline plain HTML "in sync" without hassling with ugly <f:verbatim>
tags. So it's not needed anymore. There are also no useful use cases for the tag anymore, expect of possibly some premature performance optimizations, but still then, you should not use it in combination with dynamic data as obtained by Expression Language.
Related questions:
- (Dis)advantages of JSF 2.0
Put an immediate attribute set to true on the commandButton.
<h:commandButton id="gameSelector" value="Play" action="#{gameBean.changeGame}" immediate="true" />
It will execute the method in the ApplyRequestValues phase then.
I removed the f:verbatim tag, and now it works properly. I still don't understand why it has caused this behaviour though.