JSF:如何在validateLongRange失败时隐藏outputText

时间:2013-02-28 15:49:47

标签: validation jsf

我有以下代码:

<h:form>
    <h:inputText id="inputField" value="#{bean.myProperty}">
        <f:validateLongRange
            minimum="#{bean.minimum}"
            maximum="#{bean.maximum}"/>
    </h:inputText>
    <h:commandButton id="submit" value="Submit" >
        <f:ajax execute="inputField" render="outputField errors" />
    </h:commandButton>
    <h:outputText id="outputField" value="#{bean.myPropertyFormatted}"/>
    <h:message id="errors" for="inputField"/>
</h:form>

当inputText验证失败时,我想从用户中删除/隐藏outputText。什么是最优雅和未来重构的方法来做到这一点?

我尝试在outputText元素上设置属性rendered="#{!facesContext.validationFailed}",但这只会确定是否重新呈现outputText元素,而不是保持旧文本不变。但是,当validateLongRange验证失败时,我想完全删除/隐藏用户的outputText,因为用户将查看验证错误消息,并且不想根据之前的有效输入查看旧的输出消息,这是仍然是存储在bean中的值。

3 个答案:

答案 0 :(得分:5)

作为JSF的经验法则,如果你想有条件地渲染任何东西,你应该将它包装在容器组件(<foo:panel/>)中,并使容器组件成为ajax update。

<h:form>
   <h:inputText id="inputField" value="#{bean.myProperty}">
      <f:validateLongRange
        minimum="#{bean.minimum}"
        maximum="#{bean.maximum}"/>
   </h:inputText>
   <h:commandButton id="submit" value="Submit" >
      <f:ajax execute="inputField" render="thePanel errors" />
   </h:commandButton>
   <h:panelGrid id="thePanel">
   <h:outputText rendered="#{!facesContext.validationFailed}" id="outputField" value="#{bean.myPropertyFormatted}"/>
   </h:panelGrid>
   <h:message id="errors" for="inputField"/>
</h:form>

对于要进行ajax更新的组件,它必须已经在浏览器的DOM中,这就是ajax的工作方式。因此,当您最初呈现视图时,由于outputField条件评估为false,rendered不存在。因此,任何后续的ajax更新请求都将失败,因为上述原因。容器组件策略是确保对标记区域进行全面更新,而不管之前的是什么

答案 1 :(得分:3)

问题在于,当您将rendered属性设置为对象且其值为false时,该组件将不在组件树中,因为未呈现并且您无法重新生成渲染(或更新)它。解决方案是将组件设置在UIContainer内并渲染容器:

<h:commandButton id="submit" value="Submit" >
    <f:ajax execute="inputField" render="pnlResult" />
</h:commandButton>
<h:panelGrid id="pnlResult">
    <h:outputText id="outputField" value="#{bean.myPropertyFormatted}"
        rendered="#{not facesContext.validationFailed}" />
    <h:message id="errors" for="inputField"/>
</h:panelGrid>

答案 2 :(得分:1)

根据kolossus和Luiggi Mendoza的优秀答案,我最终做了以下事情:

<h:form>
    <h:inputText id="inputField" value="#{bean.myProperty}">
        <f:validateLongRange
            minimum="#{bean.minimum}"
            maximum="#{bean.maximum}"/>
    </h:inputText>
    <h:commandButton id="submit" value="Submit" >
        <f:ajax execute="inputField" render="outputField errors" />
    </h:commandButton>
    <h:panelGroup layout="block" id="outputGroup">
        <h:outputText id="outputField" value="#{bean.myPropertyFormatted}" rendered="#{not facesContext.validationFailed}"/>
        <h:message id="errors" for="inputField"/>
    </h:panelGroup>
</h:form>

我选择h:panelGroup代替h:panelGrid,因为我的网站开发人员背景让我对基于表格的布局的想法感到不寒而栗。它与layout="block"一起显示为h:panelGroup<div/>呈现为h:panelGrid