Passing action methods in Facelets using array notation

When I was first learning facelets, I often ran into a problem when I was passing an action method into an included facelet file. For instance, I had file1.xhtml, which would include my custom tag component file2.xhtml (defined within my taglib.xml file.) file2.xhtml had a commandLink or commandPrompt that needed an action. Since I would re-use file2.xhtml and allow it to call different actions, I needed a way to pass the action method to file2.

The first thought was to include it as an attribute of my component.

   myActionAttribute="${mybean.myaction}" />

and then within file2, which in this case is mapped to mytag:

<h:commandLink value="${mybean.myValue}" action="${myActionAttribute}" />

When I tried to execute this, faces would complain to me that mybean had no myaction property. I knew it did and would be endlessly frustrated by this.
The answer is to reference the action method using array notation. On any bean referenced in facelets you can reference the properties using dot notation, as in ${mybean.myaction}, OR you can also reference it using array notation, such as ${mybean[“myaction”]}.
I never did dig in far enough in order to figure out exactly what was going on under the hood, but I’m guessing ${mybean.myaction} was actually evaluated before being sent to mytag. In order to avoid this, pass the bean, and then pass the action method as a string to the component, such as:

   myActionMethod="myaction" />

Notice that the method is just a string. Then in your component, reference it in array notation ( how many times can I say array notation! )

<h:commandLink value="${mybean.myValue}" action="${myActionController&#91;myActionMethod&#93;}" />

Notice that the method is NOT quoted. myActionMethod will be replaced by the String value passed in the value of the attribute, and that method on the bean will be called as the action of the commandLink.

10 thoughts on “Passing action methods in Facelets using array notation

  1. My pleasure, Gonzo. I ran into this more times than I would like to admit, so I’m just hoping I can save someone else the headache.

    1. In JSF 1.2 you can’t pass arguments directly to the action method. You would need to use a param or attribute tag to pass additional information to the server. I’ll try to get a post up in the next couple of days that talks about how to do that.

  2. End what if I wanted to pass a parameter to that method.
    Something like this action=”${myActionController[myActionMethod](parameter)}” is not working.

    1. Note my reply to Daniel above. You can’t pass parameters in JSF 1.2, so to pass the additional information you would need to use a param or attribute tag. It may be possible in the latest version of JSF, but I haven’t played with it. I’ve moved on to other frameworks.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s