如何有条件地渲染f:selectItem标签?

问题描述 投票:35回答:7

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

例如,我想要的东西如下:

<f:selectItem itemLabel="Yes! I need a girlfriend!"
             rendered="false(or some boolean condition)"
             itemValue="o1"/>
jsf rendered-attribute
7个回答
64
投票

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

<p:selectOneMenu>的情况下,您可以添加一些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;
}

<h:selectOneMenu>的情况下,你更依赖于webbrowser是否支持通过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;
}

服务器端的替代方案是在各个<c:if>周围引入一个JSTL <f:selectItem>,以便按顺序将其添加到视图中(确保您了解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<SelectItem>,并将其与<f:selectItems>绑定。


6
投票

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

select option[disabled] { display: none; }

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


3
投票

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

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

然后只有当布尔条件为真时才会呈现项目。


3
投票

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

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


1
投票

基于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]然后它放入一个具有你想要的值的项目。


0
投票

对我来说,“最干净”的方式是在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;
}

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


-2
投票

我解决了这个问题

<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>
© www.soinside.com 2019 - 2024. All rights reserved.