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

时间:2011-08-03 19:18:41

标签: jsf rendered-attribute

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

例如,我想要类似的东西:

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

8 个答案:

答案 0 :(得分:60)

<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中的工作方式:{ {3}}):

<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>绑定。

答案 1 :(得分:6)

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

select option[disabled] { display: none; }

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

答案 2 :(得分:3)

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

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

答案 3 :(得分:3)

您可以将其包装到ui:fragment代码中:

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

然后只有在布尔代码为真时才会呈现项目。

答案 4 :(得分: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]时,它会放入一个包含您想要的值的项目。

答案 5 :(得分: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;
}

其优点是列表中仍然可以有禁用元素。

答案 6 :(得分:0)

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

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

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

答案 7 :(得分:-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>