Question

When viewing this page with ?mode=test, the button doesn't work. It loads this page without ?mode=test, but h:panelGroup is rendered (because mode is set somewhere else). I use two methods of sending mode (h:inputHidden f:param) and to the server and nothing helps. View scoped bean is not available in CDI. What is the possible solution to this?

XHTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <f:view>
        <f:metadata>
            <f:viewParam name="mode" value="#{test.mode}" />
        </f:metadata>
        <h:panelGroup layout="block" rendered="#{test.mode.equals('test')}">
            <h:form>
                <h:inputHidden value="#{test.mode}" />
                <h:commandButton value="Run a method" action="#{test.method}">
                    <f:param name="mode" value="#{test.mode}" />
                </h:commandButton>
            </h:form>
        </h:panelGroup>
        <h:messages />
    </f:view>
</html>

Java

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

@Named("test")
@RequestScoped
public class TestBean {
    private String mode;

    public void method() {
        System.out.print(mode);
    }

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }
}
Was it helpful?

Solution

You've got a wide range of possibilities. The easiest one for you is not to bind the view parameter to the backing bean, just keep it bound to the view:

test.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
    <f:metadata>
        <f:viewParam name="mode" value="#{mode}" />
    </f:metadata>
    <h:form rendered="#{mode eq 'test'}">
        <h:commandButton value="Run a method" action="#{test.method(mode)}" />
    </h:form>
    <h:messages />
</f:view>
</html>

Test.java

@Named
@RequestScoped
public class Test {

    public void method(String mode) {
        System.out.print(mode);
    }

}

If you however would like to switch to @ViewScoped, CDI compatible annotation is now available in JSF 2.2 version. The namespaces you're using suggest you do use that version, so go with it. For JSF prior versions, there's also the chance to do it with custom Omnifaces' annotation.

See also:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top