JSF2.0 Composite Component actionListener

MikeR picture MikeR · Dec 7, 2011 · Viewed 9.5k times · Source

I am in need of some assistance in getting my Composite Component to behave. I am still learning the ropes in JSF, so please excuse any ignorance that might be displayed in this post.

So, I am working with JSF 2.0 and decided to build a composite component to make this particular code snippet reusable. The component displays everything perfectly, but will not behave at all when trying to add the actionListener.

Here is the code for my component

<ui:composition
    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"
    xmlns:composite="http://java.sun.com/jsf/composite">

    <composite:interface displayName="columnUpdate">
        <composite:attribute name="id" 
            required="true" 
            displayName="id"
            shortDescription="Id to apply to this control and its child components">
        </composite:attribute>
        <composite:attribute 
            name="value" 
            displayName="value"
            required="true" 
            shortDescription="Field that will hold the new updated value.">
        </composite:attribute>

        <composite:attribute 
            name="columnName" 
            displayName="columnName"
            required="true" 
            shortDescription="Value that will be applied as the column header">
        </composite:attribute>
        <composite:attribute 
            name="text"
            displayName="text"
            shortDescription="Text to be displayed above the field">
        </composite:attribute>

        <composite:actionSource name="actionEvent" targets="saveEvent"></composite:actionSource>
    </composite:interface>

    <composite:implementation>
        <h:outputLabel value="#{cc.attrs.columnName}" onclick="showWindow('#{cc.attrs.id}')"></h:outputLabel>

        <div id="#{cc.attrs.id}" class="ccColumnUpdate">
        <div id="windowClose" onclick="closeWindow('#{cc.attrs.id}');" style="top: -10px;" title="Close this window">CLOSE</div>
            <div>
                <h:outputLabel id="lblTitle" value="#{cc.attrs.text}"></h:outputLabel>
            </div>
            <div>
                <h:inputText id="txtValue" value="#{cc.attrs.value}"></h:inputText>
            </div>
            <div style="text-align:right;">
                <h:commandButton id="saveEvent" value="Save"></h:commandButton>
            </div>
        </div>
    </composite:implementation>
</ui:composition>

Here is the code in my page that uses the component:

<al:columnUpdate id="cuExpenseAmount" value="#{expense.columnValue}" columnName="Expense Amount" text="Set Expense Amount to:">
  <f:actionListener for="actionEvent" binding="#{expense.updateColumnValue}">
    <f:ajax execute="@form"></f:ajax>
  </f:actionListener>
</al:columnUpdate>

and here is my code on the Backing Bean:

public void updateColumnValue(ActionEvent event) throws ParseException{
    //Got HERE

}

I am not receiving any errors or hit any breakpoints I set on the backing bean. Any help, or pointers in the right direction would be appreciated.

Regards,

Mike

Answer

MikeR picture MikeR · Dec 8, 2011

I found the answer after playing around a little bit and more searching.

Changes to the composite component: FROM:

<composite:actionSource name="actionEvent" targets="saveEvent"></composite:actionSource> 

<h:commandButton id="saveEvent" value="Save"></h:commandButton>  

TO:

<composite:attribute name="registerButtonActionListener" method-signature="void actionListener(javax.faces.event.ActionEvent)" />

<h:commandButton id="saveEvent" value="Save" actionListener="#{cc.attrs.registerButtonActionListener}">
                    <f:ajax execute="@this" event="click"></f:ajax>
                </h:commandButton>

Changes to the page using the composite component:

<al:columnUpdate id="cuExpenseAmount" value="#{expense.columnValue}" registerButtonActionListener="#{expense.updateColumnValue}" columnName="Expense Amount">
                            </al:columnUpdate>

The big change was defining the method signature in the composite attribute.

Regards,

Mike