1

Primefaces 8 Java 11

I would like to add a controller attribute to a commandButton which takes in page bean instance as value . I can then use this page bean in command button renderer to disable the button by calling method on page bean.

Component Bean class

@FacesComponent(CustomCommandButton.COMPONENT_TYPE) 
public class CustomCommandButton extends CommandButton
{
    private static final Logger logger = Logger.getInstance(CustomCommandButton.class);
    public static final String COMPONENT_FAMILY = "com.xxx.faces.component"; 
    public static final String COMPONENT_TYPE = "com.xxx.faces.component.CustomCommandButton"; 

    private enum PropertyKeys {
        controller
    }
    private IpmsBean controller;
    
    @Override 
    public String getFamily() { 
         return COMPONENT_FAMILY; 
    } 

    @Override 
    public String getRendererType() { 
         return CustomCommandButtonRenderer.RENDERER_TYPE; 
    } 
    public CustomCommandButton()
    {
        super();
    }
    
    public void setController(IpmsBean bean)
    {
        getStateHelper().put(PropertyKeys.controller, bean);
        this.controller=bean;
    }
    
    public IpmsBean getController()
    {
        return (IpmsBean) getStateHelper().eval(PropertyKeys.controller, null);
    }
}

Renderer class which doesn't have whole lot just yet:

@FacesRenderer( 
     componentFamily=CustomCommandButton.COMPONENT_FAMILY, 
     rendererType=CustomCommandButtonRenderer.RENDERER_TYPE 
) 
public class CustomCommandButtonRenderer extends CommandButtonRenderer {
     public static final String RENDERER_TYPE = "com.xxx.faces.component.CustomCommandButtonRenderer";

     @Override
     public void encodeEnd(FacesContext context, UIComponent component)
                throws java.io.IOException {
          //plan is to disable button after asking pagebean
          //if (component.getController().shouldDisable())
          //     component.setDisabled("true");
          //
          super.encodeEnd(context, component);
     }
}

taglibs-faces.xml

<?xml version="1.0"?>
<facelet-taglib version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    id="lu">
    <namespace>http://com.xxx.faces/ui</namespace>
    <tag>
        <tag-name>customCommandButton</tag-name>
        <component>
            <component-type>com.xxx.faces.component.CustomCommandButton</component-type>
            <renderer-type>com.xxx.faces.component.CustomCommandButtonRenderer</renderer-type>
        </component>
        <attribute>
            <description>
                <![CDATA[Any instance of IpmsBean.]]>
            </description>
            <name>controller</name>
            <required>false</required>
            <type>com.xxx.xxxx.client.jsf.bean.IpmsBean</type>
        </attribute>
     ...copied rest of commandbutton's attributes here...
    </tag>
</facelet-taglib>

xhtml page:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    template="/resources/layout/masterLayout.xhtml"
    xmlns:c="http://xmlns.jcp.org/jsf/core"
    xmlns:incl="http://java.sun.com/jsf/composite/includes"
    xmlns:lu="http://com.xxx.faces/ui">

        <lu:customCommandButton 
            value="Custom Button" 
            controller="#{regionPolicyBean}"
            oncomplete="hello()"/>
     ....
</ui:composition>

"Custom Button" shows up just fine. But setController(bean) method is not valled. setOnComplete() method is called. Not sure what am I missing here.

I did refer to this answer Adding Custom Attributes to Primefaces Autocomplete Component in JSF but still not sure why setter is not being called.

1 Answer 1

1

Not a direct answer, but I don't see why you do this the hard way. You can simply do:

<p:commandButton ...>
    <f:attribute name="controller" value="#{...}"/>
</p:commandButton>

and get controller from the component's attributes map.

Sign up to request clarification or add additional context in comments.

1 Comment

I thought about that. If someone forgets to add or removes that attribute by mistake, application may not behave the way it is expected. If I cannot make it work with inline attribute, I will have to fallback to this with additional junit cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.