<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>
の場合、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>
を持ち込んで、次のようにそれをビューに継続的に追加することです(JSFでのJSTLの動作に注意してください: JSF2 FaceletsのJSTL ...理にかなっていますか? ):
<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; }
ただし、JSFで適切に修正する必要があります。
ui:fragment
コードにラップできます:
<ui:fragment rendered="false(or some boolean condition)">
<f:selectItem itemLabel="Yes! I need a girlfriend!" itemValue="o1"/>
</ui:fragment>
次に、ブール条件がtrueの場合にのみアイテムがレンダリングされます。
<c:if>
は、 `コンポーネントの繰り返し変数に依存している場合も機能しません(最初のビルドフェーズでは機能しますが、ajaxを使用してfor-eachのコレクションを更新すると失敗し、一部のアイテムが2回表示され、その他は表示されません)
これはJSFの大きな問題の1つです。無効化は常にオプションとは限りません。そのため、このような「簡単な」ことに対処するには、Beanでより多くのコードが必要です。
BalusCの答えを基に、新しいバージョンのJSFでバッキングBeanリストなしでそれを行うことができます(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>
いくつかの特定の要件を持つ複合コンポーネントにそれをラップしました。この質問に関連する部分は、f:selectItems
または[]
のいずれかの値を持つ[1]
の使用です。条件で[]
を使用する場合、完全に省略され、[1]
を使用する場合、必要な値を持つ単一の項目に配置されます。
私にとって「最もクリーンな」方法は、2019年にJSF 2.3を使用し、jsf/html
とjstl
を混在させないようにすることです。
itemDisabled="true"
を設定し、jsf/passthrough
pt:class="hidden"
を使用するカスタムクラス。<f:selectItem itemValue="itsValue" itemLabel="example"
itemDisabled="#{exampleBean.hideItem}"
pt:class="#{exampleBean.hideItem ? 'hidden' : ''}" />
原因はCSSスタイルが必要です
.hidden {
display: none !important;
}
これには、リストに無効な要素がまだあるという利点があります。