JSF Composite Component with conditional popup panel

1.1k views Asked by At

I'm trying to render a composite component that shows a popup panel based on the outcome of a backing bean method. So far no success. Would appreciate some help.

  • GlassFish 4.1
  • Mojarra 2.2
  • RichFaces 4.5.4

Composite Component (conditionalActionLink.xhtml):

<ui:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">

<composite:interface>
    <composite:attribute name="value"/>
    <composite:attribute name="style"/>
    <composite:attribute name="disabled"/>
    <composite:attribute name="render"/>
    <composite:attribute name="message" />
    <composite:attribute name="renderedBtn" type="java.lang.Boolean"/>
    <composite:attribute name="condition" required="true" method-signature="java.lang.Boolean action()"/>
    <composite:attribute name="execAction" required="true" method-signature="void action()"/>
</composite:interface>
<composite:implementation>
    <ui:debug hotkey="x" />
    <h:form>
        <a4j:commandLink id="actnlnx" value="#{cc.attrs.value}" oncomplete="#{managePurchases.billHasPaymentsApplied ? showMessage() : submitToServer() }" style="#{cc.attrs.style}" disabled="#{cc.attrs.disabled}"/>
        <a4j:jsFunction name="showMessage" onbegin="#{rich:component('noticeDialog')}.show()" execute="@form"/>
        <a4j:jsFunction name="submitToServer" action="#{cc.attrs.execAction}" render="#{cc.attrs.render}" execute="@form"/>             

        <rich:popupPanel id="noticeDialog" modal="true" autosized="true" resizeable="false" style="FONT-SIZE: large;">
            <f:facet name="header" style="FONT-SIZE: large;">
                <h:outputText value="Notice" />
            </f:facet>
            <f:facet name="controls">
                <h:outputLink value="#" onclick="#{rich:component('noticeDialog')}.hide(); return false;">
                    X
                </h:outputLink>
            </f:facet>
            <h:outputText value="#{cc.attrs.message}"/>
            <br/><br/>
            <h:commandButton value="Ok" onclick="#{rich:component('noticeDialog')}.hide(); return false;" style="FONT-SIZE: large;"/>
        </rich:popupPanel>  
    </h:form>
</composite:implementation>

Invoking page:

<cc:conditionalActionLink value="Delete" style="FONT-SIZE: large;text-decoration:none" message="This bill has payments applied. Please delete payments first." condition="#{managePurchases.billHasPaymentsApplied}" execAction="#{managePurchases.deleteBill}"/>

Btw, I need to use the condition value in the composite component, but challenged with how to avoid nested EL expression: oncomplete="#{cc.attr.condition ? showMessage() : submitToServer() }"

Backing Bean:

public Boolean getBillHasPaymentsApplied(){
    applogger.entry();
    //if(bill.getPayments().size() > 0)
        return applogger.exit(true);
    //else
        //return applogger.exit(false);
}

public void deleteBill(){
    applogger.entry();

    applogger.debug("DELETE BILL HERE.");
    //billDaoBean.deleteBill(bill);

    applogger.exit();

}

I've tried many tweaks, with much search online. With this particular version, error message is

javax.el.ELException: Function 'showMessage' not found

I am seeking a way to achieve this behavior.

Thanks for your help in advance!

1

There are 1 answers

4
Zim On BEST ANSWER

The oncomplete attribute of the <a4j:commandLink> component must evaluate to a String. Here, your EL tries to invoke either a showMessage() or a submitToServer() java method depending on a boolean value, which are not found.

what you want is a String with the JS function name, so just put function names between single quotes to make them String:

oncomplete="#{managePurchases.billHasPaymentsApplied ? 'showMessage()' : 'submitToServer()'}"

I dont have any RichFaces-ready playground (by the way, never used RichFaces either), so I can't test, but it should do the trick !