I tried to attach an event-listener to a composite component as follows:
<cc:interface>
<cc:attribute name="listener" method-signature="void listener(javax.faces.event.ComponentSystemEvent)" />
<cc:attribute name="value" />
</cc:interface>
<cc:implementation>
<h:inputText value="#{cc.attrs.value}">
<f:event type="preRenderComponent" listener="#{cc.attrs.listener}" />
</h:inputText>
</cc:implementation>
with the using page having this:
<ofc:testComp value="#{testAction.testInt}" listener="#{testAction.doWhatever}" />
and the backing bean like so:
public void doWhatever(ComponentSystemEvent event) {
System.out.println(testInt);
System.out.println("I was here");
}
This results in a PropertyNotFoundException: doWhatever
cannot be found on testAction
When searching the web I found this very similar solution. The main difference here is that the event parameter has been omitted. When I do the same in my scenario, it works (which I find confusing, because the documentation for f:ajax and f:event states the listener must to conform to void listener(AjaxBehaviorEvent)
and void listener(ComponentSystemEvent)
respectively)
The problem is: I'm trying to do all of this exactly because I need to get back to the original sender of the event via event#getComponent
So the question is: Is there a way to pass the event parameter in this kind of setup?
Background: I need to perform some additional validation on a range of fields. Basically, I want to hook into the lifecycle after the model has been updated, perform some calculation and possibly abort before the invoke application phase if values don't fit. The offending field needs to be marked.
I played around with the normal validation mechanism for a while, but the calculation uses the model values, which will not have been updated yet at that point. I am aware, that even if I get the above code running, preRenderView
will be too late to stop actions, but I am thinking about keeping an hidden input, which currently does the job of failing validation under the hood, and just adding the listener to actually mark the real offending field. But for this, I need the event ... any ideas?
Thanks in advance.
Update: this answer here uses the same principle, but also runs into problems as soon as the parameter is added - only I get a different error.