Reputation: 163
<h:form id="formEdit">
<p:selectOneMenu value="#{testView.selection}"
required="true">
<f:selectItem itemValue="noMenu" itemLabel="selectOneMenu not rendered"/>
<f:selectItem itemValue="haveMenu" itemLabel="selectOneMenu rendered"/>
<p:ajax update="formEdit"/>
</p:selectOneMenu>
<p:panel>
<p:selectOneMenu id="conditionallyRnedered" value="#{testView.value}"
rendered="#{testView.selection eq 'haveMenu'}"
required="true">
<f:selectItem itemValue="#{null}" itemLabel="-" noSelectionOption="true"/>
</p:selectOneMenu>
</p:panel>
<p:messages id="messages"/>
<p:commandButton value="Submit"/>
</h:form>
Component "conditionallyRnedered"
is required, and rendered on page after i select "haveMenu"
value in first menu. This component have only empty option and initialy its not rendered on page. If i press Submit button, then response is:
<partial-response><changes>
<update id="javax.faces.ViewState"><![CDATA[stateless]]></update>
</changes></partial-response>
There is no validation error. If i change value of rendered
attribute in "conditionallyRnedered"
from "#{testView.selection eq 'haveMenu'}"
to just "true"
, then response is:
<partial-response><changes>
<update id="javax.faces.ViewState"><![CDATA[stateless]]></update>
<extension ln="primefaces" type="args">{"validationFailed":true}</extension></changes>
</partial-response>
Validation error returned. The questions is:
UPD
Originally in my question is absent Bean source code, in which Bean declared as @ViewScoped
. After read @BalusC comment, i try to change scope from @ViewScoped
to @SessionScoped
, and after that validation is working correctly. Wherein javax.faces.ViewState
in response changed from stateless
to some view id:
<update id="javax.faces.ViewState">-5902669082498843838:729675320168079573</update>
I still doubt, this is solution or still workaround, because I thought that instance of @ViewScoped
bean is exist while we dont left the page. Maybe this behavior is caused by the fact that in the same page present another bean, with @SessionScoped
scope.
Upvotes: 2
Views: 1724
Reputation: 1108722
It failed for the technical reason explained in this Q&A: Form submit in conditionally rendered component is not processed. In a nutshell, JSF will re-check the rendered
attribute during processing the form submit/conversion/validation and skip components which aren't rendered during that moment. The answer is to use a @ViewScoped
bean.
That it still failed in spite of that you're actually using a @ViewScoped
bean is because you're using a stateless view via <f:view transient="true">
, as confirmed by the actual javax.faces.ViewState
value and What is the usefulness of statelessness in JSF? In other words, JSF won't save/restore the view, including any view scoped beans. Those beans will technically behave like @RequestScoped
beans and thus be recreated on every request, resetting their properties to defaults everytime.
To solve your problem, just turn off stateless view by removing <f:view transient="true">
and keep your bean @ViewScoped
.
Upvotes: 3
Reputation: 980
@bobzer,
primefaces commandButton has become ajax="true" by default. So when i set ajax="false", the form is submitted and i can see validation errors
My xhtml:
<h:form id="formEdit">
<p:selectOneMenu value="#{testView.selection}" required="true">
<f:selectItem itemValue="noMenu"
itemLabel="selectOneMenu not rendered" />
<f:selectItem itemValue="haveMenu" itemLabel="selectOneMenu rendered" />
<p:ajax update="formEdit" />
</p:selectOneMenu>
<p:panel>
<p:selectOneMenu id="conditionallyRnedered" value="#{testView.value}"
rendered="#{testView.selection eq 'haveMenu'}" required="true">
<f:selectItem itemValue="#{null}" itemLabel="-"
noSelectionOption="true" />
</p:selectOneMenu>
</p:panel>
<p:messages id="messages" />
<p:commandButton value="Submit" ajax="false"/>
</h:form>
My Bean
package citi.manageID.framework.admin.roleMgmt;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named
@ViewScoped
public class TestView {
private String selection="";
private String value="";
public String getSelection() {
return selection;
}
public void setSelection(String selection) {
this.selection = selection;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Upvotes: -1