0

I am using a JSF template that is split into 4 parts - Header, Menubar, Content and Footer. Header contains application name, version, user name, last login, etc. details retrieved from the DB. Menu section contains a dynamic menu populated from the DB w.r.t. the user role and access. Based on the menu item, I need only the content part to be refreshed without reloading/refreshing the header, menu bar and footer. So if the menu contains a URL to SomePage.xhtml, when the menu item is clicked, SomePage.xhtml should get loaded in the content. I have checked a lot of links and solutions on the net but was not able to get this to work. Can someone please me here?

All the backing bean references in below code are to retrieve data from the DB.

BaseTemplate.xhtml

<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <h:outputStylesheet name="css/override.css" />
    <h:outputStylesheet name="css/style.css" />
</h:head>
<h:body>
    <f:loadBundle basename="messages" var="msg" />
    <f:event type="preRenderView" listener="#{homePageBean.init}" />
    <h:panelGroup id="header" layout="block">
        <ui:insert name="header">
            <ui:include src="/pages/header.xhtml" />
        </ui:insert>
    </h:panelGroup>
    <h:panelGroup id="menu" layout="block">
        <ui:insert name="menu">
            <ui:include src="/pages/menu.xhtml" />
        </ui:insert>
    </h:panelGroup>
    <h:panelGroup id="content">
        <ui:insert name="content" />
    </h:panelGroup>
    <h:panelGroup id="footer" layout="block">
        <ui:insert name="footer">
            <ui:include src="/pages/footer.xhtml" />
        </ui:insert>
    </h:panelGroup>
</h:body>
</html>

header.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<body>
    <ui:composition>
        <h:form id="frmHeader">
            <table class="hdrMainTbl">
                <tr>
                    <td width="10%">
                        <h:graphicImage value="images/logo.png" width="180 px"
                            height="40 px" />
                    </td>
                    <td width="65%">
                        <table class="hdrAppNmTbl">
                            <tr>
                                <td align="center">
                                    <h:outputText styleClass="appNameText"
                                        value="#{homePageBean.appName}" /> <br/>
                                    <h:outputText styleClass="appVersionText"
                                        value="#{msg['appVersion']} #{homePageBean.appVersion}" />
                                </td>
                            </tr>
                        </table>
                    </td>
                    <td width="20%">
                        <table class="hdrUserDtlsTbl">
                            <tr>
                                <td align="right"><h:outputText styleClass="baseFontStyle"
                                        value="#{msg['welcome']}" /></td>
                                <td><h:outputText styleClass="baseFontStyle"
                                        value="#{homePageBean.userName}" /></td>
                            </tr>
                            <tr>
                                <td align="right"><h:outputText styleClass="baseFontStyle"
                                        value="#{msg['lastLogin']}" /></td>
                                <td><h:outputText styleClass="baseFontStyle"
                                        value="#{homePageBean.lastLogin}" /></td>
                            </tr>
                        </table>
                    </td>
                    <td width="5%">
                        <h:commandLink action="#{homePageBean.logoutUser}">
                            <h:graphicImage id="logoutImg" value="images/logout.png" width="40 px"
                                height="40 px" title="Logout" alt="Logout" />
                        </h:commandLink>
                    </td>
                </tr>
            </table>
        </h:form>
    </ui:composition>
</body>
</html>

menu.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<body>
    <ui:composition>
        <h:form>
            <p:menubar model="#{homePageBean.menubar}" />
        </h:form>
    </ui:composition>
</body>
</html>

footer.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<body>
    <ui:composition>
        <table class="footerTbl">
            <tr>
                <td align="center">
                    <h:outputText value="#{msg['copyright']}" /> 
                    <h:outputLink target="_blank" value="http://www.google.com/">
                        <h:outputText value="#{msg['website']}" />
                    </h:outputLink>
                </td>
            </tr>
        </table>
    </ui:composition>
</body>
</html>

SomePage.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">
<body>
    <ui:composition template="BaseTemplate.xhtml">
        <ui:define name="content">
            <h:form>
                This is in Content section populated when one of the menu item is clicked.
            </h:form>
        </ui:define>
    </ui:composition>
</body>
</html>
Geinmachi
  • 1,251
  • 1
  • 8
  • 20
Aniket V
  • 3,183
  • 2
  • 15
  • 27
  • Maybe I'm wrong but JSF templates is only a system for working with common elements (menus, headers, footers, dialogs...) without repeat their implementation (Dont Repeat Yourself!). Your thought is oriented to SPA (Single-Page-Application) and JSF can not support it (at least natively). You would have to implement your own system of "layouts" with panels or div's and fill these with ajax operations. – Miguel Oct 14 '15 at 12:06
  • 1
    This is just page decoration using JSF templating with facelets, not SPA. Nothing bad here :) - at all. – Stephane Lallemagne Oct 15 '15 at 14:29
  • @miguel: this is not true. Partially updating pages is supported by jsf. – Kukeltje Oct 15 '15 at 17:58
  • possible duplicate of [How to ajax-refresh dynamic include content by navigation menu?](http://stackoverflow.com/questions/7108668/how-to-ajax-refresh-dynamic-include-content-by-navigation-menu) – Kukeltje Oct 15 '15 at 17:59

1 Answers1

0

There is two tricks here :

1) Check your menu model bean scope:

  • If your menu is related to user, then I guess it should be @SessionScoped
  • You can also create the menu each time on-the-fly (within getMenuModel() instead of bean constructor). Less efficient but working at least.

2) If you want the menu to be refreshed, you must set an id attribute to your menubar component

<p:menubar id="menuBar1" model="#{menuBean.model}" />

then use the update feature of Primefaces, for example when the user clicks a specific menu item (Java side : see in your menubar Bean).

item.setUpdate("menuBar1");
Stephane Lallemagne
  • 1,246
  • 11
  • 21