PrimeFacesでラベルやパネルの表示非表示を切り替える

JSFではrendered属性でコンポーネントの表示・非表示を切り替えることができます。


ただ、Ajax動作で、例えばPrimeFacesのチェックボックスやコンボボックスで表示・非表示を切り替えようとすると、単純には切り替えできません。
たとえば、チェックボックスで切り替えようと思えば、素直に書くと次のようになります。

<p:selectBooleanCheckbox value="#{switching.sw}"
                         itemLabel="上を表示">
    <p:ajax update="lblUp lblDown"/>
</p:selectBooleanCheckbox>
<br/>
<h:outputText id="lblUp" value="上" rendered="#{switching.sw}"/>
<h:outputText id="lblDown" value="下" rendered="#{!switching.sw}"/>

チェックボックスがswitching.swと連動し、それぞれのoutputTextのrenderedにswitching.swの正負が指定されているので、これでチェックボックスとテキストの表示非表示が連動しそうに思います。


ところが、これでは表示が切り替わりません。


次のように、切り替えるコンポーネントをp:outputPanelに入れる必要があります。

<p:selectBooleanCheckbox value="#{switching.sw}"
                         itemLabel="上を表示">
    <p:ajax update="lblUp lblDown"/>
</p:selectBooleanCheckbox>
<br/>
<p:outputPanel id="lblUp">
<h:outputText value="上" rendered="#{switching.sw}"/>
</p:outputPanel>
<p:outputPanel id="lblDown">
<h:outputText value="下" rendered="#{!switching.sw}"/>
</p:outputPanel>

ここで、renderedは表示・非表示を切り替えるコンポーネントに、ただしajaxのupdate指定はoutputPanelコンポーネントに対して行います。


コンボボックスでのパネルの切り替えも同様です。

<p:selectOneMenu value="#{switching.str}" >
    <p:ajax update="pnlLeft pnlRight"/>
    <f:selectItem itemLabel="選択してください" itemValue=""/>
    <f:selectItem itemLabel="左" itemValue="left"/>
    <f:selectItem itemLabel="右" itemValue="right"/>
</p:selectOneMenu>
<p:outputPanel id="pnlLeft">
<p:panelGrid columns="1" rendered="#{switching.str == 'left'}">
    <h:outputText value="左"/>
    <h:outputText value="←"/>
</p:panelGrid>
</p:outputPanel>
<p:outputPanel id="pnlRight">
<p:panelGrid columns="1" rendered="#{switching.str == 'right'}">
    <h:outputText value="右"/>
    <h:outputText value="→"/>
</p:panelGrid>
</p:outputPanel>


管理ビーンは次のようになります。

package kis;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ViewScoped
@ManagedBean
public class Switching implements Serializable{
    private boolean sw;
    public boolean isSw() {
        return sw;
    }
    public void setSw(boolean sw) {
        this.sw = sw;
    }

    private String str = "";
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
    
}


Facelet全体は次のようになっています。

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>表示切り替え</title>
    </h:head>
    <h:body>
        <h:form id="fm">
            <p:selectBooleanCheckbox value="#{switching.sw}"
                                     itemLabel="上を表示">
                <p:ajax update="lblUp lblDown"/>
            </p:selectBooleanCheckbox>
            <br/>
            <p:outputPanel id="lblUp">
            <h:outputText value="上" rendered="#{switching.sw}"/>
            </p:outputPanel>
            <p:outputPanel id="lblDown">
            <h:outputText value="下" rendered="#{!switching.sw}"/>
            </p:outputPanel>
            <br/>
            <p:selectOneMenu value="#{switching.str}" >
                <p:ajax update="pnlLeft pnlRight"/>
                <f:selectItem itemLabel="選択してください" itemValue=""/>
                <f:selectItem itemLabel="左" itemValue="left"/>
                <f:selectItem itemLabel="右" itemValue="right"/>
            </p:selectOneMenu>
            <p:outputPanel id="pnlLeft">
            <p:panelGrid columns="1" rendered="#{switching.str == 'left'}">
                <h:outputText value="左"/>
                <h:outputText value="←"/>
            </p:panelGrid>
            </p:outputPanel>
            <p:outputPanel id="pnlRight">
            <p:panelGrid columns="1" rendered="#{switching.str == 'right'}">
                <h:outputText value="右"/>
                <h:outputText value="→"/>
            </p:panelGrid>
            </p:outputPanel>
        </h:form>
    </h:body>
</html>