I have a AdminHome.xhtml page which has a dynamic include as below:
<h:form id="masterform">
<table class="DEFTABLE">
<tbody>
<tr>
<td class="CREATESTYLE">Create
<h:selectOneMenu styleClass="SELECTBOX" id="createBox" value="#{adminWindowController.actionSelection}">
<f:ajax event="change" execute=":masterform:workspace" listener="#{adminWindowController.invokeAction}" render=":masterform:workspace :masterform:taskbar createBox"/>
<f:selectItem itemValue="NONE" itemLabel="Select one..."/>
<f:selectItem itemValue="CREATE_ENTITY_DEFINITION" itemLabel="Entity Definition"/>
<f:selectItem itemValue="CREATE_ENTITY_GROUP" itemLabel="Entity Group" />
<f:selectItem itemValue="CREATE_USER" itemLabel="User" />
<f:selectItem itemValue="CREATE_USER_GROUP" itemLabel="User Group" />
</h:selectOneMenu>
</td>
</tr>
</tbody>
</table>
<h:panelGroup id="workspace">
<table class="DEFTABLE">
<tr>
<td class="WSHEIGHT" valign="top">
<ui:include src="#{adminworkspace.workspaceContent}"/>
</td>
</tr>
</table>
</h:panelGroup>
</h:form>
The above include will get page names dynamically during various ajax events triggered on AdminHome.xhtml page.
Below is one of the dynamic pages that gets loaded when the selectOneMenu changes.
<ui:composition>
<h:form id="entdefcreateform">
<h:panelGroup id="entdefpanel">
<table>
</table>
<table cellspacing="0">
<tr>
<ui:repeat value="#{adminEntityDefnController.entDefTabList}" var="tab">
<td class="#{tab == uIUtil.getRequestMapValue('activetab','General') ? 'TABBUTTONCTIVE' : 'TABBUTTON'} ">
<h:commandLink action="#{adminWindowController.TabChange}" style="border: none;">
<f:ajax execute=":masterform:entdefcreateform:entdefpanel" render=":masterform:entdefcreateform:entdefpanel"/>
<f:param name="activetab" value="#{tab}"/>
<h:outputText value="#{tab}"/>
</h:commandLink>
</td>
</ui:repeat>
</tr>
</table>
<table class="TABCONTENTTABLE">
<tr valign="top">
<td class="TABCONTENT">
<ui:include src= "#{adminEntityDefnController.entDefTabTable.get(uIUtil.getRequestMapValue('activetab','General'))}"/>
</td>
</tr>
开发者_C百科 </table>
</h:panelGroup>
</h:form>
</ui:composition>
In JSF2, <ui:include>
s are evaluated during restore view phase, not during render response phase. Therefore, they do not work dynamically (anymore). I have had the same problem after migrating from JSF 1.2 to 2.1.
I got it working by changing the action method of the bean. The trick is to return to the same page that fires the ajax request. I'm using PrimeFaces 2.2.1 and the menu fires in ajax way.
The first problem i see in your code is that you could NOT have 2 <form> : one nested in another. I guess that's why your events don't fire. I had the same problem in may code !
BTW BalusC could you explain more precisely what you did by "The trick is to return to the same page that fires the ajax request. I'm using PrimeFaces 2.2.1 and the menu fires in ajax way" This is not clear for Me
E.g. you have <ui:include src="#{bean.value}"
, where bean is view scope bean.
It is possible to still use dynamic page loading. You can use either of these 2 solutions:
Set
javax.faces.PARTIAL_STATE_SAVING
to false inweb.xml
for you project. It will trigger the jsf1.2 way of state saving.When
<ui:include/>
evaluates the value - new instance of view scope bean is created and not taken from context. As a result, the default value for src taken. If you put the bean within the session scope (which is not good) or create new session scope bean which will contain only your page path string (to minimize session size), it will resolve the issue.
Here's another tip if you want to reset this session bean value from navigation from page to page. One of the ways is to create fake method "reset()
" and put<c:if test="#{bean.reset}"></if>
before<ui:include/>
to make this initialization for your page. Reset can look like:private String lastViewId; public boolean isReset() { String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId(); if (!viewId.equals(lastViewId)) { lastViewId = viewId; //make any clean here } return false; }
精彩评论