2
votes

This is my composite component hc:rangeChooser:

<ui:component xmlns="http://www.w3.org/1999/xhtml"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:ui="http://java.sun.com/jsf/facelets"
              xmlns:cc="http://java.sun.com/jsf/composite"
              xmlns:p="http://primefaces.org/ui">
    <cc:interface componentType="rangeChooser">
        <cc:clientBehavior name="rangeSelected" event="change" targets="#{cc.clientId}:datetype"/>
    </cc:interface>

    <cc:implementation>

        <div id="#{cc.clientId}">
            <h:outputScript library="primefaces" name="jquery/jquery.js" target="head" />
            <h:outputScript library="primefaces" name="jquery/jquery-plugins.js" target="head" />
            <h:outputScript library="javascript" name="rangeChooser.js" />
            <h:outputStylesheet library="primefaces" name="primefaces.css" target="head" />
            <h:outputStylesheet library="primefaces" name="jquery/ui/jquery-ui.css" target="head"/>

            <script type="text/javascript">
                var variables = {};
                variables.formid = '#{cc.clientId}';
            </script>

            <h:selectOneMenu id="datetype" value="#{cc.attrs.selectedRange}" onchange="dateFunc();">
                <f:selectItems value="#{cc.attrs.ranges}"></f:selectItems>
            </h:selectOneMenu>

            ....

            <p:inputText id="hiddenValue" value="#{cc.attrs.range}"/>
        </div>
    </cc:implementation>
</ui:component>

When I select something in <h:selectOneMenu> I run dateFunc(); which pass selected value from it to <h:inputText>, in future it will be hidden.

Now, this is a way how I'm using this component:

<h:form id="form">
    <p:growl id="growl"></p:growl>
    <hc:rangeChooser1>
        <f:ajax event="rangeSelected"
                onevent="alert('It works');"
                listener="#{testBean.update}" 
                update=":form:growl"/>
    </hc:rangeChooser1>
</h:form>

And finally my backing bean's method:

public void update(AjaxBehaviorEvent e){
    SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy");
    text = df.format(from.getTime()) + " " + df.format(to.getTime());
     FacesContext context = FacesContext.getCurrentInstance();

     context.addMessage(null, new FacesMessage("Successful" + text,  "Your message: " + text) );
     context.addMessage(null, new FacesMessage("Second Message", "Additional Message Detail"));
}

When I change selection everything works fine except that <f:ajax> doesn't call update method of testBean, but it calls to function alert('it works');

When I use <p:remoteCommand> I can call from <f:ajax onevent="myRemote"> and then define

<p:remoteCommand name="myRemote" actionListener="#{testBean.update}" 
                 update="growl"/>

But I don't like this solution and don't understand why my approach doesn't work.

1

1 Answers

3
votes

Firstly,

<cc:clientBehavior ... targets="#{cc.clientId}:datetype" />

The value of targets attribute is wrong. It's interpreted relative to the <cc:implementation>, however the #{cc.clientId} incorrectly expects it to be interpreted relative to its NamingContainer parent. Get rid of the #{cc.clientId}: prefix.

<cc:clientBehavior ... targets="datetype" />

Don't forget to notify the author of the source where you found this misinformation. This is namely not the first time I see starters using this, so there must be some source on the Internet who's spreading this misinformation and should be informed.

Secondly,

<f:ajax ... update=":form:growl" />

The update attribute isn't supported on <f:ajax>. This is PrimeFaces-specific. You likely meant to use render.

<f:ajax ... render=":form:growl" />

Unrelated to the concrete problem: <f:ajax onevent="alert('It works');"> can impossibly work as this construct isn't supported. The value of the onevent attribute should represent the name of a function reference, not a function call. So either it's a misobservation or you oversimplified/assumed too much without actually testing it.