1

I have a JSF template which dynamically includes the content to be displayed after the user had selected it through the menu:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    template="/WEB-INF/templates/template.xhtml">

    <ui:define name="main">
        <p:panel id="content">
            <ui:include src="#{navigationMb.page}" />
        </p:panel>
    </ui:define>

</ui:composition>

One of the pages I'd like to include has a p:commandButton as follows:

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

    <div class="ui-fluid">
        <h:form>
            <p:panelGrid 
                    id="changePasswordPanel" 
                    layout="grid" 
                    columns="2"
                    styleClass="ui-panelgrid-blank">

                ...

                <p:commandButton value="Change Password"
                    action="#{changePasswordMb.changePassword}" 
                    update="changePasswordPanel"
                    icon="ui-icon-check" />
            </p:panelGrid>
        </h:form>
    </div>

</ui:composition>

Which was supposed to call the following method in my backing bean:

package com.bgasparotto.archproject.web.security;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.slf4j.Logger;

@Named
@RequestScoped
public class ChangePasswordMb {

    @Inject 
    private Logger logger;

    public void changePassword() {
        logger.info("TESTE");
    }
}

However, my changePassword method is never called. Moreover, if I simply put the content of my included page directly into my main page, it works:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    template="/WEB-INF/templates/template.xhtml">

    <ui:define name="main">
        <p:panel id="content">
            <div class="ui-fluid">
                <h:form>
                    <p:panelGrid 
                            id="changePasswordPanel" 
                            layout="grid" 
                            columns="2"
                            styleClass="ui-panelgrid-blank">

                        ...

                        <p:commandButton value="Change Password"
                            action="#{changePasswordMb.changePassword}" 
                            update="changePasswordPanel"
                            icon="ui-icon-check" />
                    </p:panelGrid>
                </h:form>
            </div>
        </p:panel>
    </ui:define>

</ui:composition>

Digging around StackOverflow, I've found this great guide by BalusC to debug my application. I've checked every possible cause but it didn't work. Also, I've tried including OmniFaces fixviewstate.js in my template but it also didn't work:

<h:body>
    <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
    ...
<h:body>

EDIT 1 Here is the code for my NavigationMb:

package com.bgasparotto.archproject.web;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;

import org.slf4j.Logger;

@Named
@RequestScoped
public class NavigationMb { 
    private String page;

    public NavigationMb() {
        this("welcome.xhtml");
    }

    public NavigationMb(String page) {
        this.page = page;
    }

    public void nav(String page) {
        this.page = page;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }
}

I've ran out of possible solutions. Any ideas?

My setup:

  • Java 8
  • Wildfly 10.1.0.Final (Java EE 7)
  • (JSF 2.2, Mojarra 2.2.13 SP1)
  • Primefaces 6.1
  • OmniFaces 2.6.4
  • CDI with Weld 2.3.5

Thanks in advance.

Bruno Gasparotto
  • 671
  • 12
  • 31
  • How exactly are you assuring that `#{navigationMb.page}` is exactly the same during processing the form submit as it was during rendering the very form? Related: https://stackoverflow.com/questions/7108668/how-to-ajax-refresh-dynamic-include-content-by-navigation-menu-jsf-spa – BalusC Aug 24 '17 at 03:21
  • You are using `action="#{changePasswordMb.changePassword}"` property, so change the method `changePassword` declaration to: `public String changePassword() {` but not `void changePassword`. – krokodilko Aug 24 '17 at 03:55
  • @krokodilko: void is a valid return 'value' as well. OP states it works when not using a `ui:include`... – Kukeltje Aug 24 '17 at 08:00
  • @BalusC if I got your question right, actually I'm refering to a different backing bean `ChangePasswordMb` when submitting the form. I only use the `NavigationMb` to change the content to the form that is expected to have the `ChangePasswordMb`. – Bruno Gasparotto Aug 24 '17 at 12:30
  • @krokodilko as stated by @Kukeltje I've already confirmed that it works with a `void` return. – Bruno Gasparotto Aug 24 '17 at 12:32
  • Yes but if the `#{navigationMb.page}` value changes during submit, then JSF won't be able to find the intented input and command components to process for the very simple reason because those are not included anymore. – BalusC Aug 24 '17 at 12:49
  • @BalusC so it means I cannot do the navigation the way I was trying to and refer to your link instead? If so, should I use `f:ajax` instead of primefaces tags? What about the replacement for `@ViewScoped` since I'm using CDI? – Bruno Gasparotto Aug 24 '17 at 13:22
  • That was not my question. Your code is fine. The problem is just not visible in the information provided so far. Perhaps you incorrectly made `#{navigationMb}` a `@RequestScoped` instead of `@ViewScoped`. You should know that request scoped beans get recreated on every new request and thus their properties get reset to defaults unless initialized otherwise in `@PostConstruct`. All you need to do is to ensure that `#{navigationMb.page}` is exactly the same during processing the form submit as it was during rendering the very form. – BalusC Aug 24 '17 at 13:24
  • @BalusC you were right, my `NavigationMb` was `RequestScoped`, then I changed to `javax.faces.view.ViewScoped` then it worked. I've edited my question providing the previous code of my `NavigationMb` if you'd like to post that as an answer. Thank you very much. – Bruno Gasparotto Aug 24 '17 at 14:21
  • That was already explained in the given link. – BalusC Aug 24 '17 at 15:13

0 Answers0