0

first, please forgive my ignorance and inability so use the search engine (i swear i have searched long and often but did not find any satisfying answer to this problem).

I have a bean implementing a action-listener compatible method:

@ManagedBean(name = "myBean")
@ViewScoped
class Bean{
    public String myAction(ActionEvent event){
        ... = event.getComponent().getAttributes().get("something");
    }
}

Then, i have a jsf component like this:

<composite:interface>
    <composite:attribute name="actionBean" required="true"/>
    <composite:attribute name="actionMethod" method-signature="void myAction(javax.faces.event.ActionEvent)" />
</composite:interface>
<composite:implementation>
        <h:form>
            <p:commandButton actionListener="#{cc.attrs.actionBean[cc.attrs.actionMethod]}">
                <f:attribute name="something" value="somevalue" />
            </p:commandButton>
        </h:form>
</composite:implementation>

It is called something like this:

<namespace:myComponent actionBean="#{myBean}" actionMethod="myAction" />

I know that this call is not working, and i wonder how to do it right!

My main intention is that i want to have a relatively generic jsf-component (would be nice to have it reusable later), that contains a button. On click to this button i want to pass an object (no simple string! in case of string i would just use action="..." and pass it via f:param). With the actionListener method i take the object via event.getComponent().getAttributes().get("something").

I think the signature void myAction(javax.faces.event.ActionEvent) is the problem that breaks passing the related method to the component, isnt it? Is it in general possible to pass method with any argument to jsf components (and if yes, how)?

So, i hope there is a possible solution to solve the general problem with altering the above strategy or maybe use something nice and different (in general i prefer not to use any hacks or workarounds, but like to use what is intended by the framework).

Thanks if somebody would find the time to point me the way! In case this question already exists, would be nice to get to the related post and have this deleted.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
the dude
  • 799
  • 9
  • 26

1 Answers1

3

Try following:

<namespace:myComponent myAction="#{myBean.myAction}"/>

And composite component:

<composite:interface>
    <composite:attribute name="myAction" 
                         required="true" 
                         method-signature="void myAction(javax.faces.event.ActionEvent)"
                         targetAttributeName="actionListener"/>
</composite:interface>
<composite:implementation>
    <h:form>
        <p:commandButton id="myAction">
            <f:attribute name="something" value="somevalue" />
        </p:commandButton>
    </h:form>
</composite:implementation>

Check composite:attribute documentation. It has several options to pass listeners to composite component. I used targetAttributeName for this.

Mikita Belahlazau
  • 15,326
  • 2
  • 38
  • 43
  • Thanks Nikita! This seems to be a nice way to do it! Anyway i have some problems to actually pass the method to the component, means when is pass `myAction="#{myBean.myAction}"` it is always searching for a _attribute_ not for a method, for debugging i tried `myAction="#{myBean.myAction(event)}"`, and the call got passed to the method, yeah! But, in `myAction(ActionEvent event){` the `event` was null ... any idea if i can access/pass the `event` from the expression-context ? Thanks anyway! – the dude Apr 27 '12 at 12:18
  • Check http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/composite/actionSource.html . You can try to add `` and then use like this: `` – Mikita Belahlazau Apr 27 '12 at 15:44