0

I know that it has been asked before, but even after after carefully reviewing various postings including Balus excellent answer 'h:commandLink / h:commandButton is not being invoked' + 'Listen and debug JSF lifecycle phases', I cannot make sense why I can not render a JSF page in my tab.

I have a PrimeFaces tab 'Rules Administration' under a CSS Tab 'Rules' that successfully displays the following Jsf file RuleAdmin2.xhtml. In that page I have a button to create a new rule.

It should update the backing bean target attribute (ruleAdminBK.target) with the value of the new screen (RuleDetails.xhtml) and render this file in the 'Rules Administration' tab.

When I debug I noticed that the 'Create New Rule' is indeed being called and the target populated with the right file 'RuleDetails.xhtml'. However the tab still displays the parent form 'RuleAdmin2.xhtml'.

When I click the link 'Rule', the entire page refresh and the 'Rules Administration' tab displays the right page (RuleDetails.xhtml).

It looks to me than the tab renders before the bean has been updated.

There is no relevant information in the log file, no messages either.

Any hint is greatly appreciated as I am running out of ideas.

Here is my code: My Facelet template (matTemplate.xhtml)

<!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:c="http://java.sun.com/jsp/jstl/core"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="sessionTimeout" http-equiv="refresh" content="#{session.maxInactiveInterval};url='/mat/errorExpired.xhtml?faces-redirect=true&amp;viewName=#{view.viewId}'" />
        <f:metadata>
            <ui:insert name="metadata">Placeholder Data</ui:insert>
        </f:metadata>

        <title><ui:insert name="title">Placeholder Title</ui:insert></title>
        <ui:insert name="head"></ui:insert>
        <style type="text/css">
            @media print {
                #header, #mainmenu, #footer
                {
                    display: none !important;
                }
                #wrapper {
                    width:760px;
                    border-left:0px solid #013f7a;
                    border-right:0px solid #013f7a;
                    margin:0 auto;
                    background:#fff;
                    padding:0 5px;
                }
            }
         </style>
    </h:head>

    <h:body>
        <h:form id="templateForm">

        <div id="wrapper">
            <ul id="mainmenu">
                <li><h:link outcome="/home3.xhtml">Home</h:link></li>        
                <li><h:link outcome="/admin/rules/RuleAdmin.xhtml">Rules</h:link></li>
            </ul>
            <div id="content"  >
                <ui:insert name="content">Content</ui:insert>
            </div>
        </div>        
        <div id="footer">
            <ui:insert name="footer" >
            </ui:insert>
         </div>
        </h:form>
    </h:body>
</html>

My main page where I define my tabs:

<?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:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core" xml:lang="en" lang="en"
      xmlns:c="http://java.sun.com/jstl/core"
      xmlns:p="http://primefaces.org/ui" >
       <ui:composition template="./../../WEB-INF/matTemplate.xhtml">
            <ui:define name="content">
                <p:tabView id="tabView" dynamic="true" cache="false" activeIndex="0">
                        <p:tab id="tab1" title="Rules Administration">     
                              <ui:include src="#{ruleAdminBK.target}" />            
                        </p:tab>  
                  </p:tabView>       
            </ui:define>
        </ui:composition>
</html>

and the backing bean being called.

@Component
@Scope("session")
public class RuleAdminBK extends BaseBean {

    private static final String _RULE_DETAILS = "/admin/rules/RuleDetails.xhtml";
    private static final String _RULE_ADMIN = "/admin/rules/RuleAdmin2.xhtml";
    private String target = _RULE_ADMIN;

public void cmdCreateNew_Click() {
        setTarget(_RULE_DETAILS);
    }

and finally the 2 JSF files: RuleAdmin2.xhtm

<?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:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core" xml:lang="en" lang="en"
    xmlns:p="http://primefaces.org/ui">
<ui:composition>
    <h:panelGroup layout="block" id="rulesAdministration">
        <h:outputText id="lblStatus" value="#{ruleAdminBK.lblStatus}" />
        <table width="100%">
            <tr>
                <td align="center"><br />
                    <h1>Rules Administration</h1> <br /> <h:outputLabel
                        id="lblErrorText1" value="#{ruleAdminBK.lblErrorText}"
                        styleClass="ValidateMsg" /></td>
            </tr>
            <tr>
                <td align="right"><p:commandButton
                        action="#{ruleAdminBK.cmdCreateNew_Click}" value="create rule" /></td>
            </tr>
        </table>
    </h:panelGroup>
</ui:composition>
</html>

RuleDetails.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:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core" xml:lang="en" lang="en"
    xmlns:p="http://primefaces.org/ui">


<f:view beforePhase="#{ruleDetailsBK.Page_BeforePhase}">
    <h:outputText value="TBD" />
</f:view>
</html>
Community
  • 1
  • 1
Cyril
  • 161
  • 2
  • 22
  • 1
    Please post code in SSCCE flavor. Is for example the presence of that `
    ` absolutely necessary in order to reproduce your concrete problem? No? Then please omit it from the code to reduce code noise. Do the same for those 1000 other tags and attributes. This way experts will spot the cause much sooner by just glancing over the code. See also http://stackoverflow.com/tags/jsf/info Do note that the code must still be copy'n'paste'n'runnable without (non-obvious) modifications in order to see the problem ourselves (and yourselves!) in a blank playground project.
    – BalusC Sep 20 '13 at 11:45
  • Thank you BalusC. I updated my code in SCCCE flavor and added comments that should help resolving it. – Cyril Sep 20 '13 at 14:11
  • That helps (although some more lines could be eliminated .. meta tags and print css are irrelevant). To exclude one and other, does it work when you hardcode `/admin/rules/RuleAdmin2.xhtml` in the ``? If so, put a breakpoint in managed bean's (post)constructor and tell if it's invoked only once per session (as you told it to, by annotations), or on every request? – BalusC Sep 20 '13 at 14:14
  • I added a @PostConstruct display in the bean. It's called only once. The fact that the ui:include renders the correct file after a page refresh made me look at one of your [posting](http://stackoverflow.com/questions/7108668/how-to-ajax-refresh-the-main-content-part-by-navigation-menu). is creating a new view scoped bean instance during restore view! That might be my issue. Would the solution to fix this to still define each include separately and render it conditionally by a component? – Cyril Sep 20 '13 at 15:24

1 Answers1

0

Where is the part of the code in which you update the component? Maybe you could try the following - update the component programmatically inside the method *cmdCreateNew_Click()* like this:

public void cmdCreateNew_Click() {
    setTarget(_RULE_DETAILS);
    //add this line and check the path to the component
    RequestContext.getCurrentInstance().update("templateForm:content:tabView");
}
Marko Jankovic
  • 145
  • 1
  • 5