I have a JSF 2 composite component that employs some Ajax behavior. I want to add a listener method to the <f:ajax> tag inside my composite component, but the listener method should be provided as a <composite:attribute> in the <composite:interface>.
The <f:ajax> tag inside my composite component is currently hard-coded to a listener like this:
<f:ajax
event="valueChange"
execute="@this"
listener="#{controller.genericAjaxEventLogger}"
render="#{cc.attrs.ajaxRenderTargets}" />
The listener method on the bean has this signature:
public void genericAjaxEventLogger(AjaxBehaviorEvent event)
throws AbortProcessingException {
// implementation code...
}
I want the composite component to be something like this so the page can supply its own event method, but I can’t figure out the correct syntax for the interface.
<f:ajax
event="valueChange"
execute="@this"
listener="#{cc.attrs.ajaxEventListener}"
render="#{cc.attrs.ajaxRenderTargets}" />
How can I do this?
UPDATED WITH SOLUTION:
I took the approach suggested by BalusC and it works great. The relevant snippets are:
The interface declaration in the composite component
<composite:interface>
<composite:attribute
name="myattributeUpdatedEventListener"
method-signature="void listener()"
required="true" />
...
</composite:interface>
The Ajax tag used in my composite component
<f:ajax
event="valueChange"
execute="@this"
listener="#{cc.attrs.myattributeUpdatedEventListener}"
render="#{cc.attrs.ajaxRenderTargets}" />
The place in my page where I use the composite component
<h:form>
<compcomp:myCompositeComponent
myattributeUpdatedEventListener="#{myBackingBean.updatedEventListenerXYZ}" />
</h:form>
And the method on my backing bean
public void updatedEventListenerXYZ() {
// do something here...
}
If you can get rid of the
AjaxBehaviorEventargument,then you can use
If the argument is mandatory (for logging?), then you need to re-specify the attribute as follows
However, this does here not work as expected with
on GF 3.1 + Mojarra 2.1.1:
I’m not sure if this is a bug or not. For that I’d need to invest some more time to naildown it. However, it was workaroundable by creating a backing component which gets the
MethodExpressionfrom the attributes and invokes with the right number of arguments. Here’s a complete kickoff example:with
Regardless, I believe that the backing component puts doors open for new ways to achieve the functional requirement you have had in mind anyway 😉