i have been struggling getting this to work for 2 weeks, I am trying to merge info from BalusC from these 2 posts to (link1 link2) to achieve partial page rendering of a center content area via a menu on the left. So the links on the left would update the center content via partial page rendering using <f:ajax>
or maybe <a4j:ajax>
via richfaces
------------------------------------------------------ | include1 link | | | include2 link | center content like include1.xhtml | | include3 link | | ------------------------------------------------------
my page-layout.xhtml (master template to be used by include1.xhtml, include2.xhtml,..)looks like this.
<h:body>
<div id="top" class="top">
<ui:insert name="top">page-layout default top content</ui:insert>
</div>
<div>
<div id="left">
<h:form id="navigationFormId">
<f:ajax render=":contentForm">
<h:commandLink value="include1"
action="#{navigationBean.setPage('include1')}" />
<p></p>
<h:commandLink value="include2"
action="#{navigationBean.setPage('include2')}" />
<p></p>
<h:commandLink value="include3"
action="#{navigationBean.setPage('include3')}" />
<p></p>
</f:ajax>
</h:form>
</div>
<div id="content">
<ui:insert name="content">
<h:panelGroup id="contentPanelGroup" layout="block">
<h:form id="contentForm">
<h:panelGroup rendered="#{navigationBean.page == 'include1'}">
<ui:include src="include1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{navigationBean.page == 'include2'}">
<ui:include src="include2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{navigationBean.page == 'include3'}">
<ui:include src="include3.xhtml" />
</h:panelGroup>
</h:form>
</h:panelGroup>
</ui:insert>
</div>
</div>
</h:body>
NavigationBean.java is defined as a ViewScoped bean via CDI with @Named
public class NavigationBean implements Serializable {
public NavigationBean() {}
public String getPage() {return page;}
public void setPage(String p) {page = p;}
private String page = "include1";
}
the included pages are file like include1.xhtml and include2.xhtml and should be loaded into center content when the left menu links are clicked, here is a sample include2.xhtml
<h:body>
<ui:composition template="page-template.xhtml">
<ui:define name="content">
include2
<h:form>
form components for include2
</h:form>
</ui:define>
</ui:composition>
</h:body>
I am getting FileNotFoundException, although the stack trace does not tell which one, but removing the
<h:panelGroup rendered=".....>
<ui:include src="..." />
</h:panelGroup>
tags removes the exception. I think this is the proper implementation to accomplish this based on 2 of BalusC posts, but just can't get it to work.
The error you are getting suggests the include...xhtml page can not be found. Where are the files located? They should be in the same directory as the page-layout.xhtml file? To simplify everything I would just test if the include works, yuo can replace this:
<h:form id="contentForm">
<h:panelGroup rendered="#{navigationBean.page == 'include1'}">
<ui:include src="include1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{navigationBean.page == 'include2'}">
<ui:include src="include2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{navigationBean.page == 'include3'}">
<ui:include src="include3.xhtml" />
</h:panelGroup>
</h:form>
with:
<h:form id="contentForm">
<ui:include src="include1.xhtml" />
</h:form>
i was able to get a design via JSF2/Ajax and richfaces4 (other implementations would be ok I assume) where a left navigation menu item, implemented via templates, is able to render the center content of a template via ajax, preventing a full page refresh, and the flicker effect it has.
my navigationmenu.xhtml code looks like this
<ui:composition>
<h:form id="navigationFormId">
<rich:collapsiblePanel id="carrierCollapsibleId" header="Links that update center content" switchType="client">
<h:commandLink id="linkId1" action="/page1" value="Update Center Content with page1">
<a4j:ajax execute="@form" render=":centerContentDiv,:centerForm" />
</h:commandLink>
<br />
<h:commandLink id="linkId2" action="/page2" value="Update Center Content with page2">
<a4j:ajax execute="@form" render=":centerContentDiv,:centerForm" />
</h:commandLink>
</rich:collapsiblePanel>
...
</h:form>
I believe the render=":centerContentDiv,:centerForm"
attribute for the a4j:ajax
tags can be changed to just render=":centerForm"
but have not tested that. I know the both work together however. also, i tried JSF2 ajax tags with white space between the IDs and got errors, so i went to richfaces 4.x's a4j and then could use commas if no space was used.
now, in order for this to work, each pageX.xhtml file, for example page1.xhtml would need to have <h:form id="centerForm">
, here is an example of page1.xhtml
<ui:composition template="/templates/uiTemplate.xhtml">
<ui:define name="center_content">
<h:form id="centerForm">
<!-- put your components in here -->
</h:form>
</ui:define>
</ui:composition>
one limitation is each view that uses the template must define a <h:form id=centerForm" ...>
otherwise JSF2 will complain it can't find the render target.
my uiTemplate.xhtml file has code for the header, footer, but the pertinent part that has the navigation and center content defined is as follows
<div class="header_content">
<div id="left">
<ui:include src="navigationMenu.xhtml" />
</div>
<div id="center_content">
<!-- think this panelGroup wrapper can be -->
<!-- removed. need to test that though -->
<h:panelGroup id="centerContentDiv" layout="block">
<ui:insert name="center_content" />
</h:panelGroup>
</div>
</div>
来源:https://stackoverflow.com/questions/7746221/how-to-do-partial-page-rendering-center-content-with-jsf2-templating-via-ajax