1

I have a form with, say a text field and a multi-select field.

<h:form id="form2">
    <h:messages for="text3" />
    <h:inputText id="text3" value="#{danielBean.text3}" required="true"/>
    <br/>

    <h:messages for="select1" />
    <h:selectManyMenu id="select1" value="#{danielBean.selStrings}"
        style="height:8em;" required="true"/>
        <f:selectItems value="#{danielBean.allStrings}" var="_item" itemLabel="#{_item} (length #{_item.length()})" />
    <br/>
    <p:commandButton
        value="Submit"
        action="#{danielBean.save()}"
        update=":form2"
    >
</h:form>

On submit, both get validated, and if validation is successful, the relevant variables in the backing bean are updated. Fair enough.

The problem happens when the validation (of the multi-select) is NOT successful. In my Bean, I have (particularly for the List<String>s allStrings and selStrings)...

@PostConstruct
public void init() {
    text3 = "";

    allStrings.clear();
    allStrings.add("This");
    allStrings.add("is");
    allStrings.add("a");
    allStrings.add("test");

    selStrings.clear();
    selStrings.add("a");
}

...so that the multi-select has one pre-selected option. If the user unselects that option (i.e. no options chosen), the validation will -of course- fail, an error message will be displayed...

...but the multiselect will not be empty. It will show the content from the bean, i.e. "a" selected. This is confusing to the user - getting an error message "input required", and being shown a filled-out field.

This appears to be a feature of JSF's lifecycle, see this article by BalusC:

"When JSF renders input components, then it will first test if the submitted value is not null and then display it, else if the local value is not null and then display it, else it will display the model value."

This works fine for the text field text3, because it submits as an empty string, not null.

The problem is that zero selected options from a multi-select means that the submitted value is null, that the local copy (I guess, since it's the first submit) is null, so that the model value ("a" selected) is displayed.

I do not want that.

How can I force JSF to use the null value it got submitted when rendering the validation response?

Thanks in advance
Antares42

4

1 回答 1

1

对此没有解决方案(除了向 JSF 人员报告问题和/或在 JSF 源代码中进行黑客攻击)。但是有一种解决方法:仅更新提交时确实需要更新的组件。目前,您已设置 ajax 来更新整个表单。只更新消息怎么样?

<h:messages id="text3_m" for="text3" />
...
<h:messages id="select1_m" for="select1" />
...
<p:commandButton ... update="text3_m select1_m" />

如果您有很多字段,您可以在必要时使用PrimeFaces 选择器来最小化样板:

<h:messages for="text3" styleClass="messages" />
...
<h:messages for="select1" styleClass="messages" />
...
<p:commandButton ... update="@(.messages)" />
于 2013-09-13T12:36:11.200 回答