如何为<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/html
与jstl
混合到
- set
itemDisabled="true"
and - 一个使用
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>