How to conditionally render an f:selectItem tag?

2019-01-07 17:59发布

How can I specify a conditional rendering for an <f:selectItem> tag. I need to display <f:selectItem> options according to a specific user's status.

For example, I wanted something like:

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

6条回答
叛逆
2楼-- · 2019-01-07 18:25

The workaround I use is setting the itemDisabled attribute and using this CSS:

select option[disabled] { display: none; }

But it needs to be fixed properly in JSF.

查看更多
再贱就再见
3楼-- · 2019-01-07 18:25

I solved my problem doing this

<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
查看更多
手持菜刀,她持情操
4楼-- · 2019-01-07 18:26

Building off of BalusC's answer, it's possible to do it without a backing bean list in newer versions of JSF (I'm using JSF 2.2):

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

I wrapped it in a composite component with some specific requirements. The part related to this question is using f:selectItems with a value of either [] or [1]. When your condition makes it use [] then it will be omitted entirely, and when it uses [1] then it puts in a single item with the values you want.

查看更多
叼着烟拽天下
5楼-- · 2019-01-07 18:28

<c:if> for me is also not working if it depends on the repeated variable of a ` component (on first build phase it works but using ajax and updating the collection of the for-each it fails, showing some items twice and others not)

this is really one big issue in JSF. Disabling is not always an option, and this way much more code is necessary in the bean to address such "easy" things.

查看更多
We Are One
6楼-- · 2019-01-07 18:31

The <f:selectItem> does not support the rendered attribute. Your closest bet is the itemDisabled attribute which still displays the item, but makes it unselectable. This is also supported in <f:selectItems>.

In case of <p:selectOneMenu> you can then just add some CSS to hide disabled items.

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

In case of <h:selectOneMenu> you're more dependent on whether the webbrowser supports hiding the disabled options via 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;
}

The server side alternative is to bring in a JSTL <c:if> around the individual <f:selectItem> to contitionally add it to the view like this (make sure you're aware of how JSTL works in 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" />

Or, you could simply dynamically populate a List<SelectItem> in the backing bean based on the calculated conditions and bind it with <f:selectItems>.

查看更多
兄弟一词,经得起流年.
7楼-- · 2019-01-07 18:34

You can wrap it into ui:fragment code:

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

Then item will be rendered only when boolean codition is true.

查看更多
登录 后发表回答