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&#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.

Advertisements

10 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

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

    Comment by eryz — 2012/11/22 @ 2:39 am

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

      Comment by digitaljoel — 2012/11/23 @ 11:06 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 )

Google+ photo

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

Connecting to %s

Blog at WordPress.com.