11

I'm creating a simple menuing composite component in JSF 2. However, I am unable to pass a String attribute into the composite component to use in the action attribute of the <h:commandLink>. My component looks like:

<composite:interface>
    <composite:attribute name="title" required="true" type="java.lang.String"/>
    <composite:attribute name="view" required="true" />
</composite:interface>

<!--implementation-->
<composite:implementation>
    <li><h:commandLink action="#{cc.attrs.view}" value="#{cc.attrs.title}" /></li>
</composite:implementation>

How can I get an action String into the action attribute of the <h:commandLink>?

Jim Tough
  • 14,843
  • 23
  • 75
  • 96
Brian Leathem
  • 4,609
  • 1
  • 24
  • 44

2 Answers2

23

Looks like this attracts the Horstmanns :-)

You must name the attribute "action" and use retargeting. Then some special handling kicks in that is described with exquisite clarity (not) at

http://docs.oracle.com/javaee/6/javaserverfaces/2.0/docs/pdldocs/facelets/composite/attribute.html

and the API doc of ViewDeclarationLanguage.retargetMethodExpressions (not ViewHandler) whose link I am not allowed to paste in.

Here is how you do it.

<composite:interface>
    <composite:attribute name="title" required="true" type="java.lang.String"/>
    <composite:attribute name="action" targets="view" required="true" />
</composite:interface>

<!--implementation-->
<composite:implementation>
    <li><h:commandLink id="view" value="#{cc.attrs.title}" /></li>
</composite:implementation>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
cayhorstmann
  • 3,192
  • 1
  • 25
  • 17
1

You need to define the type of the attribute to be a method like this:

<composite:attribute name="view" method-signature="java.lang.String f()"/>

Or alternatively, some attribute names are handled specially in jsf. So if you name your attribute "action" it should also work without the method-signature:

<composite:attribute name="action"/>

Edit: I probably misunderstood the question, if you want to link to a view id without calling an action you can use the h:link tag instead of h:commandLink:

<h:link outcome="#{cc.attrs.view}" value="#{cc.attrs.title}"/>
Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
  • Both of these give a "ClassCastException: java.lang.String cannot be cast to javax.el.ValueExpression" when a String is passed as the view (or action). – Brian Leathem May 17 '10 at 22:58
  • Thanks, again, but what I'm aiming for is building a composite component that behaves like a native component, whereby it can take either a String, or a Method as the value of the action attribute. Perhaps this is simply not possible with the composite component templating, and perhaps the full component API is necessary to achieve this. – Brian Leathem May 19 '10 at 16:33
  • On second thought, you answered my question with the bit about <h:link>. I will post a new question about making a component that behaves like a native component. – Brian Leathem May 26 '10 at 18:51