tags:

views:

292

answers:

2

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>?

A: 

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
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
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
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
+2  A: 

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

https://javaserverfaces.dev.java.net/nonav/docs/2.0/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>
cayhorstmann
That's perfect, thanks Cay - It's great to have an expert like you join the stackoverflow community!
Brian Leathem