1

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.

Community
  • 1
  • 1
user825402
  • 189
  • 3
  • 13
  • Your template approach is confusing and non-sensible. I have the impression that you misunderstood the last paragraph of [this answer](http://stackoverflow.com/questions/7108668/how-to-ajax-refresh-the-main-content-part-by-navigation-menu/7113961#7113961). I did not mean that you should mix the both approaches. I did mean that you should use the one **or** the other. I suggest to revert the changes so that you end up with the same examples as shown in the answer (or forget the ajax-loading and go for the pure master template approach with plain vanilla links). – BalusC Oct 13 '11 at 12:38
  • yes BalusC, that is exactly what I thought from your last paragraph in the post, it did not say use one or the other so I thought I could use templating with that approach was possible. So let me ask this. Is partial page rendering WITH templating via facelets easily done. I see richfaces showcase and icefaces showcase doing this, but primefaces does a whole page refresh when clicking left links. BTW. it is sensible if the thought was to combine templating and you suggested way to do ppr :-) – user825402 Oct 13 '11 at 13:58
  • You can combine them, but not this way. The `` is at a non-sensible place. Further I think you meant to use `template="page-layout.xhtml"` instead of `template="page-template.xhtml"` (not that this would work as you'd expect, but that was at least the cause of the FNFE). – BalusC Oct 13 '11 at 14:07
  • BalusC, u r right, thanks for the correction. i have a typo in the post. includedX.xhtml should reference template name page-layout.xhtml. can you point me to an example on how to combine them to accomplish a faeclets version of partial page rendering with menu/content design. I am really struggling on how to do this and willing to read and investigate, just can't find a place that succinctly shows how. BTW, thanks for taking time to reply, i appreciate it and read many of you blogs and posts – user825402 Oct 13 '11 at 14:51

2 Answers2

0

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>
Ross
  • 3,008
  • 1
  • 22
  • 27
  • thanks ross, good suggestion, I have tried that , just blindly include one of the includes in an attempt to get it to work. all files are in the root directly so path issues should not be a problem, i believe its something more to do with JSF. If I just print out the value of the navigation bean, `"#{navigationBean.page}` of course I get no exception, and it does show me it is trying to include includeX.xhtml, just that `` does not work :-( – user825402 Oct 13 '11 at 14:03
  • ross, BalusC pointed out i had a typo in my includeX.xhtml files, so that is fixed, thanks for your response, still waiting to see if someone can show me how to do facelets partial page rendering, will post a solution if I come up with one. – user825402 Oct 13 '11 at 16:01
  • One thing i would like to note for those who try to implement this, it is a bit tricky, I had to make some code changes, but had the basic idea correct, you have to update a and not just a
    , going to post an example below
    – user825402 Dec 07 '11 at 22:29
0

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>
user825402
  • 189
  • 3
  • 13