Is it possible to call parameterized method-signature inside a composite-component?
Asked Answered
T

3

5

im currently creating a JSF composite-component with a method signature that can accept parameters.

Here's the excerpt :

<composite:interface>
    ....
    <composite:attribute name="activateHeroMethod" method-signature="java.util.List action(id.co.sofcograha.core.Dto, id.co.sofcograha.core.Dto)" />
</composite:interface>

<composite:implementation>
    ....
    <p:commandLink value="#{hero.map['heroName']}"
        process="@this"
        update="#{cc.attrs.update}"
        oncomplete="infoRaceDialog.hide()"
        image="ui-icon ui-icon-search">
        <f:setPropertyActionListener value="#{hero}"
            target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" />
    </p:commandLink>
    ....
</composite:implementation>

target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" fails horribly with the following error message :

javax.faces.view.facelets.TagAttributeException: /resources/sofco/infoRace.xhtml @57,76 target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" /resources/sofco/infoRace.xhtml @57,76 target="#{cc.attrs.activateHeroMethod(infoRaceBean.race, hero)}" Illegal attempt to pass arguments to a composite component lookup expression (i.e. cc.attrs.[identifier]).
        at com.sun.faces.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:401)
        at com.sun.faces.facelets.tag.TagAttributeImpl.getValueExpression(TagAttributeImpl.java:351)
        at com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler.applyAttachedObject(SetPropertyActionListenerHandler.java:128)
        at com.sun.faces.facelets.tag.jsf.core.SetPropertyActionListenerHandler.apply(SetPropertyActionListenerHandler.java:101)

Is it possible to call the parameterized method from a composite-component's attribute ? I think i can deal with multiple as a workaround of working with multiple parameters in one method, but i dont like the approach, since it'll grow in size along with the parameters.

I could wrap every params into 1 wrapper object, but im still curious whether there's a way to solve the problem of calling the method with multiple params.

Please share your thoughts !

Thank you.

Timothee answered 7/7, 2011 at 4:9 Comment(2)
@MattHandy : It has been quite a time the last time i was in a JSF project, but i think i didnt find a good solution for this, since i didnt share the answer. Sorry.Timothee
Thanks anyway, Albert. Meanwhile I found a question with an answer by BalusC who states, that it is not possible to set the method parameters inside the composite component.Punctuality
E
8

Yes is possible to do that, do it like this:

<composite:interface displayName="Image uploader with preview list">
        <composite:attribute name="backingBean" required="true" />
        <composite:attribute name="imageType" required="true"  />
</composite:interface>
....
<p:commandButton  value="Save"  actionListener="#{cc.attrs.backingBean.imageUploaded(cc.attrs.imageType)}"/>

Hope this helps some body.

Embolectomy answered 2/4, 2012 at 16:28 Comment(0)
C
0

Composite component:

<ui:component
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:cc="http://java.sun.com/jsf/composite"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:p="http://primefaces.org/ui"
>

    <cc:interface>

        <cc:attribute name="header" type="java.lang.String" required="true"/>

        <cc:attribute name="value" required="true"/>
        <cc:attribute name="update" type="java.lang.String" required="false" default=""/>
        <cc:attribute name="controller" required="true"/>

        <cc:attribute name="addLine" required="true" method-signature="void addLine()"/>
        <cc:attribute name="deleteLine" type="java.lang.String" required="true"/>

    </cc:interface>

    <cc:implementation>

        <div id="#{cc.clientId}">

            <p:panel header="#{cc.attrs.header}">

                <p:dataTable id="table" value="#{cc.attrs.value}" var="line">

                    <p:column headerText="#{cc.attrs.header}">
                        <h:outputText value="#{line.entry}"/>
                    </p:column>

                    <p:column width="32">
                        <f:facet name="header">
                            <p:commandButton title="#{msgs.add}" icon="fa fa-plus"
                                             type="button">
                                <f:ajax listener="#{cc.attrs.addLine}" render="#{cc.attrs.update} table"/>
                            </p:commandButton>
                        </f:facet>
                        <p:commandButton title="#{msgs.delete}" icon="fa fa-minus"
                                         type="button">
                            <f:ajax listener="#{cc.attrs.controller[cc.attrs.deleteLine](line)}" render="#{cc.attrs.update} table"/>
                            <p:confirm message="#{msgs.deleteString}" icon="ui-icon-alert"/>
                        </p:commandButton>
                    </p:column>

                </p:dataTable>

            </p:panel>

        </div>

    </cc:implementation>

</ui:component>

Page:

<ui:composition
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
        xmlns:any="http://java.sun.com/jsf/composite/components"
>

    <!--@elvariable id="controller" type="org.controllers.AnyController"-->
    <any:row
            header="#{msgs.subjective}"
            value="#{controller.entity.things}"
            update="form:growl form:save"
            controller="#{anyController}"
            addLine="#{anyController.addTheLine}"
            deleteLine="deleteTheLine"/>

</ui:composition>

Controller:

@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class AnyController
{
    ...

    public void addTheLine()
    {
        ...
    }

    public void deleteTheLine(final Line anyLine)
    {
        ...
    }

    ...
}
Carbajal answered 4/2, 2017 at 20:45 Comment(0)
F
0

to any person who has the same problem could try something like this

<composite:attribute name="methodName" method-signature="java.lang.String f(java.lang.String, java.lang.String)" required="false" />
Fichte answered 22/2, 2018 at 13:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.