You indeed need to transfer the very same boolean properties to the next request. You can in theory use <h:inputHidden value="#{bean.boolean1}" />
for this, but unfortunately those will only be set during update model values phase, while you actually need it to be available during apply request values phase. Besides, they will also go lost when a validation error occurs.
There are three ways to fix this non-intuitive behaviour of h:inputHidden
(I've ever filed a bug against it at the Mojarra issue list, but they didn't seem to do anything with it).
First is to use the binding
on the h:inputHidden
instead:
<h:inputHidden binding="#{bean.hidden1}" />
This however requires changes in the way you get/set the boolean values in the backing bean code. For example:
private HtmlInputHidden hidden1 = new HtmlInputHidden(); // +getter +setter.
public void setBoolean1(boolean boolean1) {
hidden1.setValue(boolean1);
}
public boolean getBoolean1() {
return (Boolean) hidden1.getValue();
}
Second is to use Tomahawk's t:saveState
instead.
<t:saveState value="#{bean.boolean1}" />
The major advantage is that you don't need to change anything in the backing bean code. It will restore the value early before the apply request values phase. You only need to add extra libraries if not done yet, but as Tomahawk provides much more advantages than only the t:saveState
, such as the in basic JSF implementation missing components/features t:inputFileUpload
, t:dataList
, t:dataTable preserveDataModel="true"
, t:selectOneRadio layout="spread"
and so on, it is worth the effort.
The third way is to store them in a session scoped bean, but you actually don't want to do that for request scoped variables. It would only give "wtf?" experiences when the enduser has multiple tabs/windows open in the same session.
Edit: as per the comments, here's an SSCCE of the second way:
JSF page:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<f:view>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<h:form id="form">
<h:inputHidden binding="#{myBean.hidden}" converter="javax.faces.Boolean" />
<h:commandButton value="submit" action="#{myBean.submit}"/>
<h:outputText value="Current boolean value: #{myBean.hidden.value}" />
</h:form>
</body>
</html>
</f:view>
MyBean class:
package mypackage;
import javax.faces.component.html.HtmlInputHidden;
public class MyBean {
private HtmlInputHidden hidden = new HtmlInputHidden();
public void submit() {
if (hidden.getValue() == null) {
hidden.setValue(true); // Set to true on 1st submit.
} else {
hidden.setValue(!((Boolean) hidden.getValue())); // Toggle true/false.
}
}
public HtmlInputHidden getHidden() {
return hidden;
}
public void setHidden(HtmlInputHidden hidden) {
this.hidden = hidden;
}
}
The relevant part of faces-config.xml
:
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>mypackage.MyBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Playground environment is JSF 1.2_13 on Tomcat 6.0.20.