Sannu
Sannu

Reputation: 1276

Adding an attribute to primefaces by extending commandButton component

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.

Upvotes: 1

Views: 532

Answers (1)

Jasper de Vries
Jasper de Vries

Reputation: 20158

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.

Upvotes: 1

Related Questions