0

i would like to add a composite component programmatically and add a action listener for a primefaces commandbutton over a interface attribute. Problem: The listener method will never be executed.

My composite component with the delcard listener attribute:

    <composite:interface>
        <composite:attribute name="bean"/>
        <composite:attribute name="listener" required="false" method-signature="void reportClickedAction(javax.faces.event.ActionEvent)"/>
    </composite:interface>
    <composite:implementation>
        <h:outputScript library="js/composite" name="KpiPast.js"/>
            <h:panelGroup rendered="#{cc.attrs.bean.showButtons}">
                <p>
                    <h:form>
                        <!-- Primefaces button using the listener -->
                        <p:commandButton id="testbutton" value="prime" ajax="true" actionListener="#{cc.attrs.listener}"/>
                    </h:form>
                </p>
            </h:panelGroup>

        </div>
    </composite:implementation>

If i use this component in a .xhtml file, like the following example, it works.

<qc:kpi-past bean="#{dynamicPageController.kpipast}" listener="#{statisticController.reportClickedAction}" />

Buf if i render it programmatically like in this post the listener method does not get called if i click the button. I use omnifaces for rendering. Here is the render code:

    UIComponent composite = Components.includeCompositeComponent(parent, Content.CONTENT_LIBRARYNAME, KpiPast.RESOURCENAME, this.getId());

    Map<String, Object> attributes = composite.getAttributes();
    // create MethodExpression
    MethodExpression listener = Components.createMethodExpression("#{statisticController.reportClickedAction}", Void.class, javax.faces.event.ActionEvent.class);
     // add MethodExpression as attribute
    attributes.put("listener", listener);
    attributes.put("bean", this);
    parent.getChildren().add(composite);

And here is my listener Method:

public void reportClickedAction(ActionEvent actionEvent) {
    logger.info("reportClickedAction");
}

What am i doing wrong? And why do the listener in my programmatically generated composite elements only work if the page gets submitted? For testing purposes i also tried a with ajax event instead of , same result, it is not working.

But while testing i saw that once a form gets submitted (with no specific action value) the page gets reloaded and my listeners are working as the should on first page call. For example if i submit the following form in the .xhtml which includes my generated composite elements, the page reloads and my listeners are working:

<h:form>
    <h:commandButton type="submit" value="submit"/>
</h:form>
Community
  • 1
  • 1
Buhmann
  • 1
  • 1
  • *"But while testing i saw that once a form gets submitted (with no specific action value) the page gets reloaded and my listeners are working as the should on first page call."* This is confusing. Please re-elaborate. If you fail in finding the right terms to explain the situation, just post a MCVE. By the way, `parent.getChildren().add(composite);` line is unnecessary. That's already done by `includeCompositeComponent()`. You're this way basically adding the same composite twice. – BalusC Oct 16 '15 at 13:23
  • I edited the confusing part and added a form example. – Buhmann Oct 17 '15 at 09:06
  • But when i created a MCVE i finally solved the problem. Good advice! Problem was that the parent element i pass into includeCompositeComponent was also programmatically generated but without using omnifaces, i created it this way: http://stackoverflow.com/questions/15828540/programmatically-create-and-add-composite-component-in-backing-bean . If you are still interested about the issue i created a repository reproducing the problem with included solution: https://github.com/limod/listenerMCVE Relevant part: Row.java – Buhmann Oct 17 '15 at 09:12

0 Answers0