DigitalJoel

2009/08/25

Passing action methods in Facelets using array notation

Filed under: facelets, java, JSF — digitaljoel @ 3:21 am

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.

<myns:mytag
   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:
<myns:mytag
   myActionController="${mybean}"
   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[myActionMethod]}" />

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.

8 Comments »

  1. Sweet. Thanks for the tip!

    Comment by Gonzo — 2009/09/04 @ 8:38 am

  2. 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.

    Comment by digitaljoel — 2009/09/04 @ 9:19 am

  3. Nice article. Thanks for sharing!!

    Comment by technicalbrainwave — 2009/10/18 @ 8:15 am

  4. Thanks for the hint!
    Is it possible to pass a parameter to the actionMethod?

    Comment by Daniel — 2009/11/02 @ 7:41 am

    • 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.

      Comment by digitaljoel — 2009/11/02 @ 10:20 am

  5. This and other techniques are explained in this interesting article: http://www.ibm.com/developerworks/java/library/j-facelets/

    Comment by Claudio Tasso — 2009/12/09 @ 1:43 am

  6. Many thaanks.. really I guess this saved me alot of time

    Comment by hala — 2011/03/04 @ 8:52 am

  7. [...] Passing action methods in Facelets using array notation [...]

    Pingback by Passing action methods into Facelets tags | J-Development — 2012/01/05 @ 5:14 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.