Button action method not being called when button is within a layout panel with its rendered attribute bound to a boolean defaulting to false

View: New views
1 Messages — Rating Filter:   Alert me  

Button action method not being called when button is within a layout panel with its rendered attribute bound to a boolean defaulting to false

by Chrys Rowe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi

    I have a JSF visual web application page where I have several panels
and the rendered attribute of the panels are determined at run time.

I have the rendered attribute of the panel bound to a boolean variable
in the page backing bean.  I set the boolean variable in the prerender
method depending on some other business logic.

In one of the layout panels I have a button that will submit the page form.

The issue I have is that if I set the default value of the boolean to
false and then set the same boolean to true in the prerender method,
then the action method for the button will not be called.


I have attached the JSP and backing bean files that will reproduce the
issue.  As written, when you click the button the button action method
will not be called and the text will not change.  If you edit the page
backing bean and set the boolean to a default of true and rerun the
project then clicking the button will call the button action method and
change the text.


Can someone please confirm this behavior?  The simple workaround is to
always set the boolean default to true but I spent a lot of trial and
error time figuring that out.  Did I waste my time discovering known
behavior or did I find a bug?


Thanks
Chrys

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Document   : Page1
    Created on : May 7, 2008, 8:26:14 AM
    Author     : chrys
-->
<jsp:root version="2.1" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:webuijsf="http://www.sun.com/webui/webuijsf">
    <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>
    <f:view>
        <webuijsf:page id="page1">
            <webuijsf:html id="html1">
                <webuijsf:head id="head1">
                    <webuijsf:link id="link1" url="/resources/stylesheet.css"/>
                </webuijsf:head>
                <webuijsf:body id="body1" style="-rave-layout: grid">
                    <webuijsf:form id="form1">
                        <webuijsf:panelLayout id="layoutPanel1" rendered="#{Page1.panelVisible}" style="height: 334px; left: 48px; top: 24px; position: absolute; width: 550px">
                            <webuijsf:button actionExpression="#{Page1.button1_action}" id="button1" style="left: 216px; top: 169px; position: absolute" text="Button"/>
                            <webuijsf:staticText binding="#{Page1.staticText1}" id="staticText1" style="left: 168px; top: 96px; position: absolute" text="Button Action Method Not Clicked"/>
                        </webuijsf:panelLayout>
                    </webuijsf:form>
                </webuijsf:body>
            </webuijsf:html>
        </webuijsf:page>
    </f:view>
</jsp:root>

/*
 * Page1.java
 *
 * Created on May 7, 2008, 8:26:14 AM
 */
 
package paneltest;

import com.sun.rave.web.ui.appbase.AbstractPageBean;
import com.sun.webui.jsf.component.StaticText;
import javax.faces.FacesException;

/**
 * <p>Page bean that corresponds to a similarly named JSP page.  This
 * class contains component definitions (and initialization code) for
 * all components that you have defined on this page, as well as
 * lifecycle methods and event handlers where you may add behavior
 * to respond to incoming events.</p>
 *
 * @author chrys
 */
public class Page1 extends AbstractPageBean {
    // <editor-fold defaultstate="collapsed" desc="Managed Component Definition">

    /**
     * <p>Automatically managed component initialization.  <strong>WARNING:</strong>
     * This method is automatically generated, so any user-specified code inserted
     * here is subject to being replaced.</p>
     */
    private void _init() throws Exception {
    }
    private StaticText staticText1 = new StaticText();

    public StaticText getStaticText1() {
        return staticText1;
    }

    public void setStaticText1(StaticText st) {
        this.staticText1 = st;
    }

    // </editor-fold>

    /**
     * <p>Construct a new Page bean instance.</p>
     */
    public Page1() {
    }

    /**
     * <p>Callback method that is called whenever a page is navigated to,
     * either directly via a URL, or indirectly via page navigation.
     * Customize this method to acquire resources that will be needed
     * for event handlers and lifecycle methods, whether or not this
     * page is performing post back processing.</p>
     *
     * <p>Note that, if the current request is a postback, the property
     * values of the components do <strong>not</strong> represent any
     * values submitted with this request.  Instead, they represent the
     * property values that were saved for this view when it was rendered.</p>
     */
    @Override
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here
       
        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("Page1 Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e: new FacesException(e);
        }
       
        // </editor-fold>
        // Perform application initialization that must complete
        // *after* managed components are initialized
        // TODO - add your own initialization code here
    }

    /**
     * <p>Callback method that is called after the component tree has been
     * restored, but before any event processing takes place.  This method
     * will <strong>only</strong> be called on a postback request that
     * is processing a form submit.  Customize this method to allocate
     * resources that will be required in your event handlers.</p>
     */
    @Override
    public void preprocess() {
    }

    /**
     * <p>Callback method that is called just before rendering takes place.
     * This method will <strong>only</strong> be called for the page that
     * will actually be rendered (and not, for example, on a page that
     * handled a postback and then navigated to a different page).  Customize
     * this method to allocate resources that will be required for rendering
     * this page.</p>
     */
    @Override
    public void prerender() {
        panelVisible = true;
    }

    /**
     * <p>Callback method that is called after rendering is completed for
     * this request, if <code>init()</code> was called (regardless of whether
     * or not this was the page that was actually rendered).  Customize this
     * method to release resources acquired in the <code>init()</code>,
     * <code>preprocess()</code>, or <code>prerender()</code> methods (or
     * acquired during execution of an event handler).</p>
     */
    @Override
    public void destroy() {
    }
   
    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected SessionBean1 getSessionBean1() {
        return (SessionBean1) getBean("SessionBean1");
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected RequestBean1 getRequestBean1() {
        return (RequestBean1) getBean("RequestBean1");
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected ApplicationBean1 getApplicationBean1() {
        return (ApplicationBean1) getBean("ApplicationBean1");
    }

    public String button1_action() {
        staticText1.setText("Button 1 was pressed!!!");
        return null;
    }

    //this version allows the button action method to be called
    //private Boolean panelVisible = true;
   
    //this version does not allow the button action method to be called
    private Boolean panelVisible = false;

    public Boolean getPanelVisible() {
        return panelVisible;
    }

    public void setPanelVisible(Boolean panelVisible) {
        this.panelVisible = panelVisible;
    }
   
}