0

I'm trying to offer some content dynamically, that is without dedicated pages, with the help of buttons. The aforementioned content is correctly loaded, but it's not working.

The layout is like this:

<p:outputPanel style="width: 100%; height: 100%; overflow: auto;" id="contentPanel">
    <c:choose>
        <c:when test="#{empty requestComposition}">
            <ui:insert name="body">Content</ui:insert>
        </c:when>
        <c:otherwise>
            <ui:include src="#{requestComposition}" />
        </c:otherwise>
    </c:choose>
</p:outputPanel>

The button to load content is like this (inside another outputPanel):

    <p:commandButton value="Load Dynamic" update=":contentPanel" actionListener="#{applicationController.processActionButton('/dynamic')}" />

The action listener is like this:

public void processActionButton(String target){
    if(target == null || target.isEmpty()){
        return;
    }
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest req = (HttpServletRequest)context.getExternalContext().getRequest();
    req.setAttribute("requestComposition", "/WEB-INF/templates" + target + ".xhtml");
}

The dynamic.xhtml is like this:

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions"
    xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
    xmlns:jsf="http://xmlns.jcp.org/jsf"
    xmlns:p="http://primefaces.org/ui"
    xmlns:pe="http://primefaces.org/ui/extensions">
    <p:outputPanel style="width: 100%; padding-top: 20px;">
        <p:outputPanel style="width: 60%; margin: 0 auto;">
            <p:outputPanel style="text-align: center; color: gold; font-weight: bold;">Dynamic</p:outputPanel>
            <p:messages id="messages" />
            <h:form>
                <p:panelGrid columns="2" style="width: 100%;">
                    <p:outputLabel value="Item" for="idItem" />
                    <p:outputPanel style="display: block; padding-right: 10px;" layout="inline">
                        <p:inputText value="#{bean.item}" id="idItem" style="width: 100%;" required="true" />
                    </p:outputPanel>
                </p:panelGrid>
                <p:outputPanel style="text-align: center;">
                    <p:commandButton value="Process" style="margin: 5px;" update=":growl" onclick="PrimeFaces.widgets.widget_#{fn:replace(component.clientId, ':', '_')}.disable()" oncomplete="PrimeFaces.widgets.widget_#{fn:replace(component.clientId, ':', '_')}.enable()" actionListener="#{applicationController.dummyAction}" />
                    <p:commandButton value="Dummy" style="margin: 5px;" update=":growl" actionListener="#{applicationController.dummyAction}" process="@this" />
                </p:outputPanel>
            </h:form>
        </p:outputPanel>
    </p:outputPanel>
</ui:composition>

When any of the buttons is clicked the form apparently submits, but the action listener is not executed. When dynamic.xhtml is loaded as page content the form submits, but the action listener is triggered only for the second button (labelled Dummy), because of process @this, in which case the form is no longer submitted. I can workaround the form not submitting with process@this by adding onchange to input elements, but I failed to understand why is not working when it is loaded dynamically.

Thank you

Alex Gusta
  • 11
  • 3
  • Do you have a form in the layout too? Nothing in the browser console? – Jaqen H'ghar Feb 15 '15 at 09:50
  • I don't have nested forms and the console is clean. I'm using Chrome and the only change is in the Network tab where it shows it is posting to the server and gets OK reply back. – Alex Gusta Feb 15 '15 at 10:48
  • Is this acceptable as dupe? http://stackoverflow.com/questions/7108668/how-to-ajax-refresh-the-main-content-part-by-navigation-menu/ – BalusC Feb 16 '15 at 07:50
  • It is close. I know I could have a bean property to store the "page" to be displayed, but this approach means that when I refresh the page I will still get that content, and I don't want that to happen. The project is small so I don't want to bother with a full ACL setup. I checked the generated source and it contains the viewState hidden field, I also added the fixview script, but to no avail. – Alex Gusta Feb 16 '15 at 09:52

1 Answers1

0

I have to apologize to BalusC, since the answer he suggested was actually correct. I was tricked by the @PostConstruct which performed an unnecessary initialization for me, but the key is to use a @ViewScoped bean. That however raises another question, since it is stated in the documentation that by default there will be maximum 20 such objects stored in the server, which can be configured to a different value, but if I understood correctly that would mean that the 21st connection to the server will result in reusing the first one, so the new connection will access data not meant for it, or in discarding it and creating a new one, which means the first will lose its data?

Alex Gusta
  • 11
  • 3