b:selectOneMenu with required attribute is not ignored on immediate buttons
BootsFaces 1.3.0
Assume this example:
<b:messages />
<b:form>
<b:selectOneMenu value="#{myBean.myItem}" required="true" requiredMessage="please fill out the select field">
<f:selectItem itemValue="" itemLabel="-- please choose --" />
<f:selectItem itemValue="0" itemLabel="Zero" />
<f:selectItem itemValue="1" itemLabel="One" />
</b:selectOneMenu>
<b:commandButton action="#{myBean.cancel}" value="cancel" immediate="true" />
</b:form>
@ManagedBean
@SessionScoped
public class MyBean {
private Integer myItem;
public List<Integer> getMyItem(){ return myItem; }
public void setMyItem(){ this.myItem = myItem; }
public String cancel() {
this.myItem = null;
return "";
}
}
On clicking the cancel-button, the immediate-attribute is ignored for the selectOneMenu-component. Using the jsf-own h:selectOneMenu-component, the immediate-attribute is NOT ignored.
<b:messages />
<b:form>
<h:selectOneMenu value="#{myBean.myItem}" required="true" requiredMessage="please fill out the select field">
<f:selectItem itemValue="" itemLabel="-- please choose --" />
<f:selectItem itemValue="0" itemLabel="Zero" />
<f:selectItem itemValue="1" itemLabel="One" />
</h:selectOneMenu>
<b:commandButton action="#{myBean.cancel}" value="cancel" immediate="true" />
</b:form>
Just double-checking: "Not ignored" means that the cancel button doesn't work as long as the field is empty?
no, but as described above, the immediate attribute is ignored. On using the immediate attribute on a command button, all input component's required attributes should be ignored, but this is not the case on the b:selectOneMenu component. See http://balusc.omnifaces.org/2006/09/debug-jsf-lifecycle.html for a description about that behavior, mostly referring to the cancel-button effect.
source of knowledge https://myfaces.apache.org/wiki/core/user-guide/jsf-and-myfaces-core-concepts/how-the-immediate-attribute-works.html
approach
the handling of immediate should not be part of the component lib.
we have a diffrent in the class hierarchy
HtmlSelectOneMenu extends javax.faces.component.UISelectOne UISelectOne extends UIInput
SelectOneMenu extends SelectOneMenuCore SelectOneMenuCore extends HtmlInputText HtmlInputText extends javax.faces.component.UIInput
there is the same behavior by b:selectBooleanCheckbox
i have inspect / debug the get and setter for immediate - it work for true and false and set the value into the StateHelper
<b:messages />
<b:form>
<b:selectOneMenu value="#{myBean.myItem}"
required="true"
requiredMessage="please fill out the select field a"
immediate="false">
<f:selectItem itemValue="" itemLabel="-- please choose --" />
<f:selectItem itemValue="0" itemLabel="Zero" />
<f:selectItem itemValue="1" itemLabel="One" />
</b:selectOneMenu>
<h:selectOneMenu value="#{myBean.myItem2}"
required="true"
requiredMessage="please fill out the select field b"
immediate="false">
<f:selectItem itemValue="" itemLabel="-- please choose --" />
<f:selectItem itemValue="0" itemLabel="Zero" />
<f:selectItem itemValue="1" itemLabel="One" />
</h:selectOneMenu>
<b:selectBooleanCheckbox value="#{myBean.myItem3}"
required="true"
requiredMessage="please fill out the select field c"
immediate="false" />
<b:commandButton action="#{myBean.cancel}"
value="cancel"
immediate="true" />
</b:form>
@ManagedBean
@SessionScoped
public class MyBean {
private Integer myItem;
private Integer myItem2;
private Boolean myItem3;
public Integer getMyItem() {
return myItem;
}
public void setMyItem(Integer myItem) {
this.myItem = myItem;
}
public Integer getMyItem2() {
return myItem2;
}
public Boolean getMyItem3() {
return myItem3;
}
public void setMyItem3(Boolean myItem3) {
this.myItem3 = myItem3;
}
public void setMyItem2(Integer myItem2) {
this.myItem2 = myItem2;
}
public String cancel() {
this.myItem = null;
this.myItem2 = null;
return "";
}
}
@stephanrauh in the decode() we set menu.setValid(false) / menu.setValid(true) - is this in this phase really necessary
I'm afraid development of BootsFaces has slowed down considerably. We'll never manage to address this issue. Let's close it.