【问题标题】:How to conditionally render an f:selectItem tag?如何有条件地呈现 f:selectItem 标签?
【发布时间】:2011-10-19 09:49:41
【问题描述】:

如何为<f:selectItem> 标签指定条件渲染。 我需要根据特定用户的状态显示<f:selectItem> 选项。

例如,我想要这样的东西:

<f:selectItem itemLabel="Yes! I need a girlfriend!"
             rendered="false(or some boolean condition)"
             itemValue="o1"/>

【问题讨论】:

    标签: jsf rendered-attribute


    【解决方案1】:

    您也可以使用 JS (jQuery) 隐藏它。在 Primefaces 上:

    $('.ui-selectoneradio .ui-state-disabled').closest('tr').hide();
    

    这是给p:selectOneRadio的。注意,如果更新组件或组件的容器,必须重新运行代码。

    【讨论】:

      【解决方案2】:

      对我来说,“最干净”的方式是在 2019 年使用 JSF 2.3,以避免将 jsf/htmljstl 混合到

      1. 设置itemDisabled="true"
      2. 使用jsf/passthrough pt:class="hidden" 的自定义类。
      <f:selectItem itemValue="itsValue" itemLabel="example"
          itemDisabled="#{exampleBean.hideItem}" 
          pt:class="#{exampleBean.hideItem ? 'hidden' : ''}" />
      

      当然你需要 CSS 样式

      .hidden {
          display: none !important;
      }
      

      这样做的好处是您的列表中仍然可以有禁用的元素。

      【讨论】:

        【解决方案3】:

        我这样做解决了我的问题

        <p:selectOneRadio id="myId" value="#{myView.myProperty}">
           <h:panelGroup rendered="#{myView.showMyOption}">
              <f:selectItem itemLabel="My Option" itemValue="0"/>
           </h:panelGroup>
           <f:selectItem itemLabel="My Option 1" itemValue="1"/>
           <f:selectItem itemLabel="My Option 2" itemValue="2"/>
        </p:selectOneRadio>
        

        【讨论】:

        • 这对rendered="false"“有效”,但不适用于rendered="true"
        【解决方案4】:

        基于 BalusC 的答案,在较新版本的 JSF(我使用的是 JSF 2.2)中,可以在没有支持 bean 列表的情况下做到这一点:

                <h:selectOneMenu id="Value" value="#{cc.attrs.value}">
                    <f:selectItem itemLabel="#{cc.attrs.placeholder}" noSelectionOption="true">
                        <f:passThroughAttribute
                            rendered="#{not empty cc.attrs.placeholder}"
                            name="hidden" value=""/>
                    </f:selectItem>
                    <f:selectItems value="#{empty cc.attrs.allLabel ? [] : [1]}"
                        var="item"
                        itemLabel="#{cc.attrs.allLabel}"
                        itemValue="#{cc.attrs.allValue}"/>
                    <f:selectItems value="#{cc.attrs.codeList}" var="code" itemLabel="#{code.codeDesc}" itemValue="#{code.userCode}"/>
                </h:selectOneMenu>
        

        我将它包装在具有一些特定要求的复合组件中。与此问题相关的部分是使用 f:selectItems ,其值为 [][1]。当你的条件使它使用 [] 时,它将被完全省略,当它使用 [1] 时,它会放入一个带有你想要的值的项目。

        【讨论】:

          【解决方案5】:

          &lt;c:if&gt; 对我来说也不起作用,如果它依赖于 ` 组件的重复变量(在第一个构建阶段它可以工作,但使用 ajax 并更新 for-each 的集合失败,显示一些项目两次并且其他人没有)

          这确实是 JSF 中的一大问题。禁用并不总是一种选择,这样在 bean 中需要更多的代码来解决这些“简单”的事情。

          【讨论】:

            【解决方案6】:

            &lt;f:selectItem&gt; does not 支持 rendered 属性。您最接近的赌注是itemDisabled 属性,它仍然显示该项目,但使其无法选择。 &lt;f:selectItems&gt; 也支持这一点。

            如果是 &lt;p:selectOneMenu&gt;,您可以添加一些 CSS 来隐藏禁用的项目。

            <p:selectOneMenu ... panelStyleClass="hideDisabled">
                <f:selectItem itemValue="1" itemLabel="one" />
                <f:selectItem itemValue="2" itemLabel="two" itemDisabled="#{some.condition}" />
                <f:selectItem itemValue="3" itemLabel="three" />
            </p:selectOneMenu>
            
            .ui-selectonemenu-panel.hideDisabled .ui-selectonemenu-item.ui-state-disabled {
                display: none;
            }
            

            &lt;h:selectOneMenu&gt; 的情况下,您更依赖于网络浏览器是否支持通过 CSS 隐藏禁用的选项:

            <h:selectOneMenu ... styleClass="hideDisabled">
                <f:selectItem itemValue="1" itemLabel="one" />
                <f:selectItem itemValue="2" itemLabel="two" itemDisabled="#{some.condition}" />
                <f:selectItem itemValue="3" itemLabel="three" />
            </h:selectOneMenu>
            
            select.hideDisabled option[disabled] {
                display: none;
            }
            

            服务器端的替代方法是在单个 &lt;f:selectItem&gt; 周围引入一个 JSTL &lt;c:if&gt; 以有条件地将其添加到这样的视图中(确保您了解 JSTL 在 JSF 中的工作方式:JSTL in JSF2 Facelets... makes sense?):

            <f:selectItem itemValue="1" itemLabel="one" />
            <c:if test="#{not some.condition}">
                <f:selectItem itemValue="2" itemLabel="two"  />
            </c:if>
            <f:selectItem itemValue="3" itemLabel="three" />
            

            或者,您可以简单地根据计算的条件在支持 bean 中动态填充 List&lt;SelectItem&gt;,并将其与 &lt;f:selectItems&gt; 绑定。

            【讨论】:

            • 是的 rendered 属性不受 f:selectitem 支持,因此我提出了这个问题。顺便说一句c:if 很好地解决了这个问题。谢谢
            • 不客气。然而,它有一个警告:当它依赖于 JSF 转发器组件的重复变量(如 ui:repeath:dataTable 等)时,它不会起作用。
            • 另一种可能的解决方案是使用 ` ... 不管其他... ` 这个的优点是作为一个真正的 JSF 组件。请记住,在 JSF 2.0 上存在一个错误,如 this post 中所述。
            • @Haroldo_OK 我可以确认 ui:fragment 呈现的属性通常可以工作,但不适用于 selectItem。 (我的脸 2.1.10)
            • 据我所知,panelStyleClassstyleClass 属性在 PrimeFaces 6.1 社区版中的 p:selectOneMenu 上被完全忽略,因此显示的 CSS 定位不起作用(我假设它以前在某个阶段工作过)。
            【解决方案7】:

            你可以把它包装成ui:fragment代码:

            <ui:fragment rendered="false(or some boolean condition)">
              <f:selectItem itemLabel="Yes! I need a girlfriend!" itemValue="o1"/>
            </ui:fragment>
            

            只有当布尔编码为真时才会渲染项目。

            【讨论】:

            • 据我所知,这不适用于f:selectItem,它仍然呈现(显示为可选选项),至少在p:selectOneMenu 内。我不会对 stackoverflow 进行无评论的投票,但我认为您应该仔细检查此声明。
            【解决方案8】:

            我使用的解决方法是设置 itemDisabled 属性并使用此 CSS:

            select option[disabled] { display: none; }
            

            但它需要在 JSF 中正确修复。

            【讨论】:

            • 您能否更准确地指出在 .css 文件中应如何指定?我试过.ui-selectonemenu-list-item a:disabled,但没用。
            猜你喜欢
            • 2021-02-28
            • 2023-04-08
            • 1970-01-01
            • 2019-10-28
            • 1970-01-01
            • 2012-01-01
            • 2019-10-03
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多