Reputation: 71
I have a specific question concerning delegation an ActionListener to a composite component (jsf). I created a composite component to show (browse) and edit any personal user data (attribute "user").
<body>
<co:interface>
<co:attribute name="editAction" required="false" targets="edit" method-signature="java.lang.String f()"/>
<co:attribute name="saveAction" required="false" targets="save" method-signature="java.lang.String f()"/>
<co:attribute name="cancelAction" required="false" targets="cancel" method-signature="java.lang.String f()"/>
<co:attribute name="isBrowseModus" required="true"/>
<co:attribute name="user" required="true"/>
<co:attribute name="isDeveloper" required="true"/>
<co:actionSource name="edit"/>
<co:actionSource name="save"/>
<co:actionSource name="cancel"/>
</co:interface>
............
<p:inplace id="inpLand" editor="true"
toggleable="#{not cc.attrs.isBrowseModus}"
style="#{cc.attrs.isBrowseModus ? 'color: black' : 'color: blue'}">
<p:inputText value="#{cc.attrs.user.land}" label="text"/>
</p:inplace>
...........
<c:if test="#{cc.attrs.isBrowseModus}">
<h:commandButton id="edit" value="Edit"/>
</c:if>
........
Actually this composite component is called by a view calling myData.xhtml:
<ui:define name="center">
<h3>MyData Developer </h3>
<h4>Welcomne</h4>
<h:form id="dataForm">
<mc:UserData user="#{dataBean.user}" isDeveloper="#{dataBean.developer}" isBrowseModus="#{dataBean.browseModus}" cancelAction="#{dataBean.cancel}"
saveAction="#{dataBean.save}" editAction="#{dataBean.edit}">
<f:actionListener for="edit" binding="#{dataBean.editActionListener}"/>
</mc:UserData>
</h:form>
</ui:define>
</ui:composition>
Within the composite component there is a (id = edit) and the delivered actionListener (see f:actionListener within myData) should be bound to this commandButton (id = edit). This is my understanding after reading different forum discussion and several documentations.
Unfortunately the editActionListener method isn't fire after clicking the Edit-Button and I don't know why. Surely this editActionListener method exists within the managedBean "dataBean" (myData.java):
public void editActionListener(ActionEvent ae) {
browseModus = false;
FacesContext.getCurrentInstance().renderResponse();
}
What is my aim: Within that composite component the user is able by clicking the "edit" button to change any user data. I prefer using the inplace tag of PRIMEFACES. After clicking the edit button all the changeable fields should be shown in blue color.
My questions:
Any help would be appreciate. Many thanks in advance. Regards, Bodo
Upvotes: 1
Views: 1294
Reputation: 1108632
According to the tag documentation, the <f:actionListener binding>
must refer a concrete instance implementing the ActionListener
interface, not a method expression.
All with all, your problem can be solved by providing a concrete implementation of the ActionListener
interface via a getter which in turn invokes the desired action listener method.
private ActionListener editActionListener = new ActionListener() {
@Override
public void processAction(ActionEvent event) throws AbortProcessingException {
DataBean.this.editActionListener(event);
}
};
public ActionListener getEditActionListener() {
return editActionListener;
}
public void editActionListener(ActionEvent event) {
browseModus = false;
FacesContext.getCurrentInstance().renderResponse();
}
This is however clumsy which indicates that you're looking for the solution in possibly the wrong direction. A simpler way is to use <cc:attribute targets="edit">
instead.
<cc:interface>
...
<cc:attribute name="actionListener" targets="edit" />
</cc:interface>
which is used as
<mc:UserData ... actionListener="#{dataBean.editActionListener}" />
Upvotes: 2