0

I have the following JSF 2 template Page with primefaces menu, I want to partially update the cenral centent of the page onclick of links from left Menu, I don't want to update the entire page.I have gone throu the posts in stackoverflow, they are suggetign that I should have a form name in the central_body_div, but I don't want to sepcify a form in the central_body_div, as the dynamically loaded page will have form with it's own name, I should be able to submit the form in the page appearing dynamically in central_body_div div.

First of all the Layout page itself not loading , giving the below exception.

Cannot find component with identifier "central_body_div" referenced from "leftMenuFormId:menuItem1".

Experts can you give a solution for this problem. would apprecite your replies.

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <f:view contentType="text/html">

        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <h:outputStylesheet name="cssLayout.css" library="css" />
            <h:outputStylesheet name="default.css" library="css" />        
            <title> Lightweight Mediation - Secure Pages </title>
        </h:head>

        <h:body id="securebody">

            <div id="top">
                <ui:insert name="top">
                    <ui:include src="/secure/home/header.xhtml" />
                </ui:insert>
            </div>
            <div id="content_holder">
                <div id="left">
                    <ui:insert name="left">
                        <ui:include src="/secure/home/leftMenu.xhtml" />
                    </ui:insert>
                </div>
                <div id="central_body_div" class="left_content">
                    <ui:insert name="content">Content</ui:insert>
                </div>
            </div>
            <div id="bottom">
                <ui:insert name="bottom">
                    <ui:include src="/secure/home/footer.xhtml" />
                </ui:insert>
            </div>

        </h:body>
    </f:view>
</html>

My leftMenu.xhtml content is below

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition id="leftMenuCompositionId"> 
            <h:form id="leftMenuFormId">
                <p:menu id="lMenuId">
                    <p:menuitem id="menuItem1" value="page1" action="page1" update="central_body_div" partialSubmit="true"/>
                    <p:menuitem id="menuItem2" value="page2"  action="page2" update="central_body_div" partialSubmit="true" />
                </p:menu>
            </h:form>
        </ui:composition>
    </h:body>
</html>
Rong Nguyen
  • 4,143
  • 5
  • 27
  • 53
Muthuvel P
  • 147
  • 1
  • 7
  • 21
  • `central_body_div` not a jsf component, you try ` – Rong Nguyen May 05 '13 at 13:35
  • Hi Thanks for your suggestion, I have followed it, this change removed the error [Cannot find component with identifier "central_body_div"]. But Page is not updating, when I click on the menuitems. central_body_opt not getting new page content. – Muthuvel P May 05 '13 at 18:21
  • I am working with Primefaces 3.4.1, and my project work fine. You should debug step by step to sure where problem come from. – Rong Nguyen May 06 '13 at 01:19
  • Hi , I have tried with primefaces 3.5 , but no partial update, when I click in the menu item it redirecting to the page without header , footer and leftmenu ,[ no partial update of center content] – Muthuvel P May 07 '13 at 19:31

4 Answers4

2

Change your code with following and try again,

leftMenu.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">    
 <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>Facelet Title</title>
</h:head>
<h:body>
    <ui:composition id="leftMenuCompositionId"> 
        <h:form id="leftMenuFormId">
            <p:menu id="lMenuId">
                <p:menuitem id="menuItem1" value="page1" action="page1" update=":form1:central_body_div" partialSubmit="true"/>
                <p:menuitem id="menuItem2" value="page2"  action="page2" update=":form1:central_body_div" partialSubmit="true" />
            </p:menu>
        </h:form>
    </ui:composition>
</h:body>

and your template xhtml with,

<?xml version='1.0' encoding='UTF-8' ?> 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <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:f="http://java.sun.com/jsf/core">

<f:view contentType="text/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <h:outputStylesheet name="cssLayout.css" library="css" />
        <h:outputStylesheet name="default.css" library="css" />        
        <title> Lightweight Mediation - Secure Pages </title>
    </h:head>

    <h:body id="securebody">

        <div id="top">

        </div>
        <div id="content_holder">
            <div id="left">
                <ui:insert name="left">
                    <ui:include src="leftMenu.xhtml" />                        
                </ui:insert>
            </div>
            <h:form id="form1" >
                <h:panelGroup id="central_body_div">
                    <script type="text/javascript">alert('Content Updated')</script>
                    <ui:insert name="content">Content</ui:insert>
                </h:panelGroup>
            </h:form>
        </div>
        <div id="bottom">

        </div>

    </h:body>
</f:view>

It's checked and working.

Jitesh
  • 1,384
  • 10
  • 20
  • Hi, Partial update is not happening , in this method. I have followed all the stpes as you have instructed, when I click on the link central content is not getting changed at all. – Muthuvel P May 06 '13 at 03:50
  • This is a good way to screw up the code and not to allow for *any* form in the included page. You'd typically almost **never** want to follow that design, as it's too restrictive. – skuntsel May 06 '13 at 05:11
  • @skuntsel you are right that the design is restrictive. But I've just shown why the current design is not working. – Jitesh May 06 '13 at 06:54
  • @user782224 check out the update in this post – Jitesh May 06 '13 at 06:56
  • I have tried update=":form1:central_body_div" partialSubmit="true", but partial update not happening. – Muthuvel P May 06 '13 at 18:18
  • Check out with the new suggestion – Jitesh May 07 '13 at 18:54
  • Jitesh, thanks a lot for the detailed solution, I am getting content update alert every time when I click on left menu, some javascript error is coming, I will fixed. your answer is the solution to my problem I have accepted it. – Muthuvel P May 08 '13 at 04:39
0

Warning! View build time vs view render time problem ahead!

The usual mistake here is performing navigation, or as you say, refreshing a central holder with <ui:insert>/<ui:define>, which is a view build tag, not a view render UI component. So it simply won't be recalculated on AJAX requests, as your component tree will be restored from view state, and will not be built afresh.

So, just don't do that mistake, by making AJAX navigation, which is defective in many ways (SEO, non-bookmarkability, not user friendliness, etc.) and perform navigation by the components designed for that, like <h:link>, or <p:menuItem> that's generating plain get as.


As per your comment you don't fully distinguish between navigation links and command links. The former are used to perform navigation only and generate bookmarkable a elements, while the latter are used to (partially) submit the form, do business job, and (partially) update the view, or perform navigation.

What you need to do is simply to distinguish between those cases. For navigation use <h:link>/<p:menuitem outcome="/your-view-id">, for POST actions, use <p:commandButton>/<p:menuitem action(listener)="#{bean.action(listener)}" instead.

In this case the templating structure doesn't matter as long as you don't expect tag handlers to be refreshed on AJAX requests.

skuntsel
  • 11,624
  • 11
  • 44
  • 67
  • Hi, I am creating this site for intranet users only.I have remvoed from body, but partial update is not happening. can you Please suggest best way to do Partial updates, with a fixed template [header, footer and navigation]. – Muthuvel P May 06 '13 at 06:01
0

I have placed the solution I arrived from the discussion in this post and reference from other posts. the page we are including can have different form names.

template.xhtml

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">

    <f:view contentType="text/html">

        <h:head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <h:outputStylesheet name="cssLayout.css" library="css" />
            <h:outputStylesheet name="default.css" library="css" />        
            <title> Lightweight Mediation - Secure Pages </title>
        </h:head>

        <h:body id="securebody">

            <div id="top">
                <ui:insert name="top">
                    <ui:include src="header.xhtml" />
                </ui:insert>
            </div>

            <div id="content_holder">        
                <div id="left">
                    <ui:insert name="left">
                        <ui:include src="leftMenu.xhtml" />                        
                    </ui:insert>
                </div>
                <div id="center" class="left_content">
                    <h:panelGroup id="central_body_div">
                        <ui:include src="#{templateBean.page}.xhtml" />
                    </h:panelGroup>
                </div>       
            </div>

            <div id="bottom">
                <ui:insert name="bottom">
                    <ui:include src="footer.xhtml" />
                </ui:insert>
            </div>

        </h:body>
    </f:view>
</html>

leftMenu.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition id="leftMenuCompositionId">    

            <h:form id="leftMenuFormId">
                <f:ajax render=":central_body_div">
                    <h:commandLink value="page1" action="#{templateBean.setPage('page1')}" /><br></br>
                    <h:commandLink value="page2" action="#{templateBean.setPage('page2')}" />
                </f:ajax>
            </h:form>

        </ui:composition>
    </h:body>
</html>

Page 1

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition>              
            <h1>Page One</h1>
        </ui:composition>
    </h:body>
</html>

Page 2

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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>Facelet Title</title>
    </h:head>
    <h:body>
        <ui:composition >  
            <h:form id="form1" >
                <h1>Page Two</h1>
            </h:form>
        </ui:composition>
    </h:body>
</html>



package ae.co.gui.beans;

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.event.ActionEvent;

@Named(value = "templateBean")
@SessionScoped
public class TemplateBean implements Serializable {

    private String page;

    public TemplateBean() {
    }

    @PostConstruct
    public void init() {
        this.page = "page1"; // Ensure that default is been set.
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

}
Muthuvel P
  • 147
  • 1
  • 7
  • 21
0

Late to the party... fixing an application for a client currently and face this issue. Didn't like the idea of adding a form. They use primefaces, not sure if this is only unique to them but <p:commandButton ... update="@(:central_body_div)"/> fixed the problem in my case.

Remi Morin
  • 292
  • 2
  • 6
  • 11