I have a JSF component which is mapped on a List in the corresponding bean. As I want the mapped field to contain at least one value when the form is submitted, this field is annoted @NotEmpty.
Bean :
public class MyBean {
@NotEmpty(message="Validation failed")
private List<String> selectedOptions = new ArrayList<>();
... getter & setter
}
Each time the user select something on my component I want the selection to be immediatly mapped in the bean, so I add an ajax behaviour to the component (Here the component is a p:selectManyMenu
but the issue seems to be present with any component mapped to a List) :
XHTML :
<h:form>
<p:outputLabel for="optionslist" value="Options :" />
<p:selectManyMenu id="optionslist" value="#{myBean.selectedOptions}" style="margin-bottom:50px">
<f:selectItem itemLabel="Option 1" itemValue="1" />
<f:selectItem itemLabel="Option 2" itemValue="2" />
<f:selectItem itemLabel="Option 3" itemValue="3" />
<p:ajax process="@this" update="result optionsListMessage" />
</p:selectManyMenu>
<p:commandButton value="Submit" update="result optionsListMessage" />
<p:message for="optionslist" id="optionsListMessage" />
<p:dataList id="result" value="#{myBean.selectedOptions}" var="option">
<h:outputText value="#{option}" />
</p:dataList>
</h:form>
My issue happens in the following situation :
- The user selects one or several choices (Ctrl + click here).
- He unselects every choices he just selected.
- He submits the form.
- We can see in the result
dataList
that the last unselected value is still in the bean.
My understanding of the situation is that when the user unselects the last value, the validation fails because of the @NotEmpty annotation on the field (as confirmed by the p:message
validation failure message). As a consequence the setter is not called and the last unselected value remains in the bean.
How can I, in a proper way, allow the user to unselect every items without validation failures, and run the validator on this field only when the form is submitted ?