有没有办法防止JSF在验证错误后显示h:selectManyMenu中的先前/过期内容?

时间:2013-09-13 10:06:41

标签: validation jsf-2 lifecycle selectmanymenu

我有一个表单,例如文本字段和多选字段。

<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>

在提交时,两者都得到验证,如果验证成功,则更新辅助bean中的相关变量。很公平。

当(多选)验证失败时,会出现问题。在我的Bean中,我(特别是List<String> s allStringsselStrings)......

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

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

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

...以便多选具有一个预先选择的选项。如果用户取消选择该选项(即没有选择选项),验证将 - 当然 - 失败,将显示错误消息...

... 但多选不会为空。它将显示来自bean的内容,即选中的“a”。这使用户感到困惑 - 收到错误消息“需要输入”,并显示填写的字段。

这似乎是JSF生命周期的一个特征,请参阅this article by BalusC

“当JSF呈现输入组件时,它将首先测试提交的值是否为空然后显示它,否则如果本地值不为null然后显示它,否则它将显示模型值。“

这适用于文本字段text3,因为它提交为空字符串,而不是null。

问题是来自多选的零选项意味着提交的值为null,本地副本(我猜,因为它是第一次提交)为null,因此模型值(“a”已选中)显示。

我不想那样。

如何强制JSF在呈现验证响应时使用它提交的空值?

提前致谢
Antares42

1 个答案:

答案 0 :(得分: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 Selectors来最小化样板:

<h:messages for="text3" styleClass="messages" />
...
<h:messages for="select1" styleClass="messages" />
...
<p:commandButton ... update="@(.messages)" />