如何有条件地呈现f:selectItem标记



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

例如,我想要这样的内容:

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

<f:selectItem>不支持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>的情况下,你更依赖于浏览器是否支持通过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;
}

服务器端的替代方案是在单个<f:selectItem>周围引入JSTL <c:if>,以有条件地将其添加到视图中,就像这样(确保您了解JSTL在JSF中的工作方式:JSTL在JSF2 Facelets中……有道理吗?):

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

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

select option[disabled] { display: none; }

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

这确实是JSF中的一个大问题。禁用功能并不总是一种选择,因此在bean中需要更多的代码来解决这种"容易"的问题。的东西。

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

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

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

基于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]时,它会放入一个包含你想要的值的单项。

你也可以使用JS (jQuery)隐藏它。Primefaces:

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

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

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

  1. set itemDisabled="true" and
  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;
}

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

我解决了这个问题

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

相关内容

  • 没有找到相关文章

最新更新