1

I'm having a issue in PrimeFaces panel update.

I have one main panel which contains two output panel. Each output panel may contains one button which is swap panel. The swap panel button is used to swap the output panel from one to another.

If I update the button action for render the panels I need to provide the main panel Id it works fine. But for a tree structure hierarchy, If I mean to give the two output panel Ids It doesn't render the panel. The Button action called only once when I put the log to confirm that.

I will attach my code samples given below:

renderingPanel.XHTML

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

    <h:head>
        <title>
           Panel Rendered
        </title>
    </h:head>
    <h:body>
        <f:event listener="#{PanelRendered.initializePageAttributes}" type="preRenderComponent"/>

        <h:form id="panelFormId">
            <p:panel id="mainPanelId" widgetVar="mainPanelId">
                <p:outputPanel id="mainOutputPanel" rendered="#{PanelRendered.mainPanelRendered}">
                    <h:outputText value="hello main"/>
                    <p:commandButton id="mainSwap" value="Swap To Sub Panel" update="mainOutputPanel,subOutputPanel" action="#{PanelRendered.mainButtonAction}" icon="ui-icon-transferthick-e-w"/>
                </p:outputPanel>

                <p:outputPanel id="subOutputPanel" rendered="#{PanelRendered.subPanelRendered}">
                    <h:outputText value="hello sub"/>
                    <p:commandButton id="subSwap" value="Swap To Main" update="subOutputPanel,mainOutputPanel"  action="#{PanelRendered.subButtonAction}" icon="ui-icon-transferthick-e-w"/>
                </p:outputPanel>

            </p:panel>
        </h:form>
    </h:body>
</html>

PanelRendered.Java

public class PanelRendered
{

    private boolean mainPanelRendered;
    private boolean subPanelRendered;
    private Logger logger = Logger.getLogger(PanelRendered.class);

    public PanelRendered()
    {
         File configFile = new File("/home/nafeel/Applications/apache-tomcat-7.0.34/webapps/treetable/conf" + File.separator + "log4j.properties");
        if (configFile.exists())
        {
            PropertyConfigurator.configure(configFile.getAbsolutePath());
        }
        else
        {
            System.out.println("Configuration Logger File not available");
        }
    }

    public String mainButtonAction()
    {
        logger.info("Enter inside main button action");
        mainPanelRendered = false;
        subPanelRendered = true;
        return null;
    }

    public String subButtonAction()
    {
        logger.info("Enter inside sub button action");
        mainPanelRendered = true;
        subPanelRendered = false;
        return null;
    }

    public void initializePageAttributes()
    {
        logger.info("Enter inside initializepage");
        mainPanelRendered = true;
        subPanelRendered = false;
    }

    /**
     * @return the mainPanelRendered
     */
    public boolean isMainPanelRendered()
    {
        return mainPanelRendered;
    }

    /**
     * @param mainPanelRendered the mainPanelRendered to set
     */
    public void setMainPanelRendered(boolean mainPanelRendered)
    {
        this.mainPanelRendered = mainPanelRendered;
    }

    /**
     * @return the subPanelRendered
     */
    public boolean isSubPanelRendered()
    {
        return subPanelRendered;
    }

    /**
     * @param subPanelRendered the subPanelRendered to set
     */
    public void setSubPanelRendered(boolean subPanelRendered)
    {
        this.subPanelRendered = subPanelRendered;
    }
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ahamed Nafeel
  • 49
  • 3
  • 13

2 Answers2

2

Can you follow some guideline JAVA code

  • Use proper naming for bean as your class name is PanelRendered and you are using the same name in xhtml file and you havent post your @ManagedBean @ViewScoped so i assume your bean name on xhtml should be panelRendered not PanelRendered.
  • Use @PostConstruct to initialize variable in JSF bean. avoid to use java constructor.

XHTML code: I just change the bean name from PanelRendered to panelRendered and i am update panel like this update="mainPanelId"

And your code is working fine at my end, if you have any error please post here.

Your question But for a tree structure hierarchy, If I mean to give the two output panel Ids It doesn't render the panel.

if the component with rendered="false" it is not generated any HTML code on browser, so you did not find the id="subOutputPanel" tag in your outputed HTML code, and when you click on command button it call the back bean method and come to update update="mainOutputPanel,subOutputPanel" it did not find the subOutputPanel id and ajax call will fail, and you will not get correct behavior or UI. and from next time it did not call any thing, for stop call back bean method you can study what happened after prime faces get ajax fail. hope this will help you.

ankush yadav
  • 422
  • 3
  • 13
  • If you give mainPanelId its working fine for my page itself. But If you give the two output panel Id it doesn't work. I mean to ask for the reason. why the subPanel Id updates are not working here.? – Ahamed Nafeel Jun 30 '16 at 04:31
  • see my updated code. thanks, and if you agree please accept my ans. – ankush yadav Jun 30 '16 at 04:32
  • I understand the concept now, But how could I able to update both Id. Is it possible.? I tried the same update with two text box it works perfectly. Kindly make clear. – Ahamed Nafeel Jun 30 '16 at 04:38
1

I'm a bit of a n00b when it comes to JSF, but I have had similar issues. I think the Booleans in your PanelRendered class should have getters named as follows:

public boolean isMainPanelRendered()
public boolean isSubPanelRendered()

The expression language used in the XHTML file stays the same. It seems to be a convention that the expression language will add "is" to the front and capitalise the letter before searching the bean for the property(function or variable).

So this:

rendered="#{PanelRendered.mainPanelRendered}"
rendered="#{PanelRendered.subPanelRendered}"

stays the same. Edited: added } at last of rendered. Edited: realised it would need a getter for the private member variable

David Findlay
  • 1,296
  • 1
  • 14
  • 30
  • 1
    when we use getter and setter it automatically creates the is in prefix of the variables. I hope this is not the issue. I try it in all my projects. – Ahamed Nafeel Jun 30 '16 at 03:44
  • 1
    I haven't really been able to find documentation to back this up, but it was the experience I had in the JSF primefaces project I worked on. We were using a VCH type approach rather than a JavaBeans style, but I have no reason to believe the convention changes there. – David Findlay Jun 30 '16 at 03:48
  • By encapsulating the boolean variables will produce the getter/setter. The getter/setter may create the instance names for the expression language you mentioned on JSF. I tried also your technique but it also failed. The JSF need getter and setter to bind with Java class. – Ahamed Nafeel Jun 30 '16 at 03:55
  • So did you try with a getter named isMainPanelRendered/isSubPanelRendered? – David Findlay Jun 30 '16 at 04:02
  • 1
    yes, its failed @David Findlay. I just revise my question. It works fine for me. If I put the main panel Id. Instead of my main panel Id. I need to given my sub panel Ids It doesn't work. The problem is with the update. Don't go on with Java beans or anything. – Ahamed Nafeel Jun 30 '16 at 04:34