Search code examples
jsf-2java-ee-6composite-component

JSF2.0 - Composite component with optional method expression


I'm implementing a composite component and I found a issue which I didn't find a solution.

I specified its attributes that can or not be passed by the page author, but I couldn't specify a method attribute (a method expression to Action) that, if it wasn't passed, the composite component doesn't use the method attribute in the composite:implementation tag.

Here my code:

<composite:interface>
    <composite:attribute name="namePrompt" required="true"/>
    <composite:attribute name="actionMethod" method-signature="java.lang.String  action()" required="false"/>
    <composite:attribute name="showComponent" default="false"/>
</composite:interface>

<composite:implementation>
    <div>
       <p:commandLink actionListener="#{cc.attrs.actionMethod}"
                      rendered="#{cc.attrs.showComponent}"
                      >
            <h:outputText value="#{cc.attrs.namePrompt}"/>    
       </p:commandLink>
    </div>
</composite:implementation>

When using it, I didn't specify the "actionMethod" attribute. Like this:

<util:foo namePrompt="SomeName" showComponent="true"/>

But I get the error message:

javax.faces.FacesException: Unable to resolve composite component from using page using EL expression '#{cc.attrs.actionMethod}'

Is there a way to do this?


Solution

  • You will have to create two p:commandLink elements and render them conditionally according to definition of your parameter:

    <p:commandLink actionListener="#{cc.attrs.actionMethod}" rendered="#{!empty cc.getValueExpression('actionMethod') and cc.attrs.showComponent}">
      <h:outputText value="#{cc.attrs.namePrompt}"/>
    </p:commandLink>
    <p:commandLink rendered="#{empty cc.getValueExpression('actionMethod')}">
      <h:outputText value="#{cc.attrs.namePrompt}"/>
    </p:commandLink>