I need to load the xhtml page dynamically in the main content sectin when a menu item is selected in the left side section thus avoiding page refresh.
I have created a Prime Faces dynamic panel menu on the left section with list of sub menus and menu items for each sub menu. The menu is loaded dynamically based on the role of the logged in user. When the menu item is selected, the corresponding Action Listener is called but the pages are not loaded or displayed
The application is being developed using Prime Faces 3.4.1 / JSP 2.0 / Spring Framework 3.1.1
More Information on the Application Background
The Screen layout is divided into four sections.
Header - Logo and icons that is common to all Footer - contains Footer information Left side Bar - Contains the menu. This is dynamically populated based on the role of the logged in user Main Content - This displays the actual .xhtml pages corresponding to the selected menu item on the left side
I have used the Facelet Template to define the layout and contents. Following is the template defined
layoutTemplate.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>RF</title>
<link type="text/css" rel="stylesheet" href="# {facesContext.externalContext.requestContextPath}/javax.faces.resource/main.css.xhtml?ln=css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</h:head>
<h:body>
<f:view contentType="text/html; charset=UTF-8" encoding="UTF-8" >
<div id="outerWrapper">
<div id="pageHeader">
<ui:insert name="pageHeader">
</ui:insert>
</div>
<div id="contentWrapper">
<div id="leftPanel">
<div class="jsmenu">
<ui:insert name="leftPanel">
</ui:insert>
</div>
</div>
<div id="mainContent">
<div id="mainStyle">
<h:panelGroup id="mainOutputPanel">
<h:form id="mainContentForm">
<ui:insert name="mainContent">
</ui:insert>
</h:form>
</h:panelGroup>
</div>
</div>
<div class="clearFloat"></div>
</div>
<div id="footer">
<ui:insert name="footer">
</ui:insert>
</div>
</div>
</f:view>
</h:body>
</html>
Main Screen layout
Following is the Main screen layout which include the template defined above. I have included the header.xhtml, footer.xhtml and rfleft.xhtml which contains the dynamically populated menu. In the , I am getting the page to be loaded from the JSF backing bean
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition template="/pages/protected/templates/layoutTemplate.xhtml">
<ui:define name="pageHeader">
<ui:include src="/pages/protected/templates/loginHeader.xhtml">
</ui:include>
</ui:define>
<ui:define name="leftPanel">
<ui:include src="/pages/protected/templates/rfleft.xhtml">
</ui:include>
</ui:define>
<ui:define name="mainContent">
<ui:include id="mainPage" src="#{menuMB.screenName}">
</ui:include>
</ui:define>
<ui:define name="footer">
<ui:include src="/pages/protected/templates/footer.xhtml">
</ui:include>
</ui:define>
</ui:composition>
</h:body>
</html>
Left Menu to load the menu dynamically (rfleft.xhtml)
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:body>
<h:form id="leftMainForm">
<p:panelMenu style="width:200px" model="#{menuMB.mnuModel}">
</p:panelMenu>
</h:form>
</h:body>
</html>
JSF Backing Bean
@SessionScoped
@ManagedBean(name = "menuMB")
public class MenuMB implements Serializable {
@ManagedProperty(value = "#{LoginService}")
ILoginService loginService;
private String screenName = "";
String menuUrl = "";
User loggedUser = null;
private List<FunctionMaster> fmList = null;
private MenuModel mnuModel = new DefaultMenuModel();
public MenuMB() {
loggedUser = (User) RFContextUtil.getSessionFromContext("user");
}
@PostConstruct
public void loadMenu() {
if (loggedUser != null) {
//Load the actions to be performed by the logged user . Loading as menu item
fmList = loginService.getMenuForUser(loggedUser.getUserID());
}
createMenu(fmList);
}
private void createMenu(List<FunctionMaster> fmList) {
try {
if (fmList != null) {
for (FunctionMaster sub : fmList) {
if (sub.getParentFunctionID() == 0) {
Submenu rfSubMenu = new Submenu();
rfSubMenu.setLabel(sub.getScreenDisplayName());
getMnuModel().addSubmenu(rfSubMenu);
for (FunctionMaster item : fmList) {
if (item.getParentFunctionID() != 0) {
if (item.getParentFunctionID() == sub.getFunctionID()) {
MenuItem rfSubItem = new MenuItem();
rfSubItem.setId(item.getFunctionName() + item.getFunctionID().toString());
rfSubItem.setValue(item.getScreenDisplayName());
rfSubItem.setImmediate(true);
rfSubItem.setProcess("@form");
rfSubItem.setPartialSubmit(true);
rfSubItem.setUpdate(":mainOutputPanel");
rfSubItem.setAjax(true);
rfSubItem.setRendered(true);
//Adding Action Listener
ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
MethodExpression methodExpr = factory.createMethodExpression(FacesContext.getCurrentInstance().getELContext(), "#{menuMB.loadScreenFromMenu}", Void.class, new Class[]{ActionEvent.class});
MethodExpressionActionListener actionListener = new MethodExpressionActionListener(methodExpr);
rfSubItem.addActionListener(actionListener);
rfSubMenu.getChildren().add(rfSubItem);
}
}
}
}
}
}
} catch (Exception ex) {
String excep = ex.getMessage();
}
}
public void loadScreenFromMenu(ActionEvent event) {
MenuItem menuItem = (MenuItem) event.getComponent();
String attrName;
try {
if (menuItem != null) {
screenName = RequestFactoryContextUtil.getResourceBundleString(menuItem.getId());
//Set the screen that needs to be displayed. This is the property that is used in the Main Screen layout
setScreenName(screenName);
}
} catch (Exception exc) {
}
}
}
Any help is appreciated.
-Baskar