I have a form in JSF2 with 2 checkboxes (<h:selectBooleanCheckbox>). At least one of them should be checked. Both checked are also ok, but when none is checked, there should be error.
This validation should work also on ajax, i.e. when user checks/unchecks, error message should disappear/appear.
So I binded both checkboxes to UISelectBoolean elements and added validator to each. In validator I check value of the second checkbox, if it is false, and current checkbox is also set to false, errormessage is produced. Smth like:
if (newValue == false && secondCheckbox.getValue() == false) {
throw new ValidationException();
}
Problem is when user unchecks checkbox on the page, while the other is also unchecked, this false value doesn't go to the model, nor event to UISelectBoolean.
Scenario:
- Initially both are unchecked
- User checks checkbox1.
newValueistrue, so this is valid, goes to UISelectBoolean and model.- User unchecks checkbox1. Checkbox2 is
false,newValueisfalse, so exception is thrown. Because of failed validation, thisfalsevalue doesn't go to the model, nor even to UISelectBoolean element. - User checks checkbox2.
Truevalue goes to the model and UISelectBoolean. - U开发者_JAVA技巧ser unchecks checkbox2. Checkbox1 is still unchecked on the page, but in the model and UISelectBoolean there is still
true. So validation passes and there is no error message. On the page both checkboxes are unchecked, but in model checkbox1 is stilltrue.
How to solve such a problem?
Consider <h:selectManyCheckbox required="true">. Here's a kickoff example:
<h:form>
<h:selectManyCheckbox id="options" value="#{bean.checked}" required="true">
<f:selectItems value="#{bean.options}" />
<f:ajax render="optionsMessage" />
</h:selectManyCheckbox>
<h:message id="optionsMessage" for="options" />
<h:commandButton value="Submit" action="#{bean.submit}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:messages globalOnly="true" />
</h:form>
With
@ManagedBean
@RequestScoped
public class Bean {
private List<String> checked;
private List<String> options = Arrays.asList("first", "second");
public void submit() {
System.out.println("Checked: " + checked);
}
// ...
}
The f:ajax works fine here. Probably you've used event="click" instead of (the default) event="valueChange" which will cause that the checkmark won't be retained after render. The click is namely called right before the checkmark get visually set. The render would block the checkmark being visually set.
加载中,请稍侯......
精彩评论