読者です 読者をやめる 読者になる 読者になる

システム開発で思うところ

JavaEEを主にシステム開発をしながら思うところをツラツラを綴る

JSFのSelectItemにEnum以外の値を指定する

過去の記事への追記です。

vermeer.hatenablog.jp

セレクトボックスにEnum以外の「選択無し」という値を指定したい場合があると思います。

コードの貼り付けだけになりますが、誰かのご参考になれば
やっていることは静的ページもAjaxを使った動的ページも同じなのでAjaxのコードだけです。

ポイント

xhtml

"h:selectOneMenuoptionに選択無しの要素を追加します
<option jsfc="f:selectItem" itemLabel="#{msg['noselect']}"></option>

コード

codeがnullの場合の振舞いを追加実装

実装例

xhtml

<?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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <h:head>
        <meta charset="UTF-8" />
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <title>JSF SELECT ITEM</title>
    </h:head>
    <body>
        <form jsfc="h:form">
            <h1>JSF SELECT ITEM PATTERN Ajax</h1>
            <dir>
                <h2>Enum has code and property </h2>
                <select jsfc="h:selectOneMenu" value="#{selectItemAjax.selectItemValueEnumCodeProperty}">
                    <option jsfc="f:selectItem" itemLabel="#{msg['noselect']}"></option>
                    <option jsfc="f:selectItems" value="#{selectItemAjax.enumCodeProperty.values}"></option>
                    <f:ajax listener="#{selectItemAjax.changeItem}" render="map" event="change"/>
                </select>
            </dir>
            <hr />
            <dir>
                <h2>Map</h2>
                <select id="map" jsfc="h:selectOneMenu"  value="#{selectItemAjax.selectItemValueMap}">
                    <option jsfc="f:selectItems" value="#{selectItemAjax.selectItemMap.values}"></option>
                </select>
            </dir>
            <hr />
            <dir>
                <input type="submit" jsfc="h:commandButton" value="更新" action="#{selectItemAjax.submit()}"/>
            </dir>
        </form>
    </body>
</html>

Controller(ManagedBean)

package com.mycompany.samplejsf.domain.selectitem;

@Named(value = "selectItemAjax")
@SessionScoped
@NoArgsConstructor @Getter
public class SelectItemAjaxController implements Serializable {

    private static final long serialVersionUID = 1L;

    @Setter
    private Integer selectItemValueEnumCodeProperty;

    @Setter
    private Integer selectItemValueMap;

    private JsfSelectItem enumCodeProperty;
    private JsfSelectItem selectItemMap;

    private Map<Integer, String> dummuyMap;

    @PostConstruct
    public void init() {
        this.selectItemValueEnumCodeProperty = Gender.FEMALE.getCode();
        this.enumCodeProperty = JsfSelectItem.of(Gender.class);
        this.replaceSelectItemMap();
        this.printLog("init");
    }

    public void submit() {
        this.replaceSelectItemMap();
        this.printLog("submit");
    }

    public void changeItem(AjaxBehaviorEvent event) {
        this.selectItemValueMap = (Integer) JsfAjaxBehaviorEvent.of(event).getValue();
        this.replaceSelectItemMap();
        this.printLog("changeItem");
    }

    private void replaceSelectItemMap() {
        try {
            switch (EnumCodeProperty.codeOf(Gender.class, this.selectItemValueEnumCodeProperty)) {
                case MALE:
                    this.maleSnack();
                    break;
                case FEMALE:
                    this.femaleSnack();
                    break;
                default:
                    this.noSnack();
            }
        } catch (NullPointerException | IllegalArgumentException ex) {
            this.noSnack();
        }
    }

    private void maleSnack() {
        Map<Integer, String> map = new LinkedHashMap<>();
        map.put(1, "大福");
        map.put(2, "おはぎ");
        map.put(3, "みたらしだんご");
        map.put(4, "せんべい");
        this.selectItemValueMap = map.keySet().iterator().next();
        this.selectItemMap = JsfSelectItem.of(map);
        this.dummuyMap = map;
    }

    private void femaleSnack() {
        Map<Integer, String> map = new LinkedHashMap<>();
        map.put(5, "チョコ");
        map.put(6, "クッキー");
        map.put(7, "プリン");
        map.put(8, "ゼリー");
        this.selectItemValueMap = map.keySet().iterator().next();
        this.selectItemMap = JsfSelectItem.of(map);
        this.dummuyMap = map;
    }

    private void noSnack() {
        Map<Integer, String> map = new LinkedHashMap<>();
        map.put(0, "");
        this.selectItemValueMap = map.keySet().iterator().next();
        this.selectItemMap = JsfSelectItem.of(map);
        this.dummuyMap = map;
    }

    private void printLog(String label) {
        System.out.println("label = " + label);
        System.out.println("selectItemValueEnumCodeProperty = " + selectItemValueEnumCodeProperty);
        if (selectItemValueEnumCodeProperty != null) {
            System.out.println("selectItemValueEnumCodeProperty codeOf = " + EnumCodeProperty.codeOf(Gender.class, selectItemValueEnumCodeProperty));
        }
        System.out.println("selectItemValueMap = " + this.selectItemValueMap);
        System.out.println("selectItemValueMap value = " + this.dummuyMap.get(this.selectItemValueMap));
    }
}

message.properties

noselect=選択無し
gender_male=男
gender_female=女

実行結果

f:id:vermeer-1977:20161222155819p:plain
「選択無し」を選択したら、お菓子リストがクリアされました。
今回は初期リストは空ですが、何かしら意味のあるリストを設定しても良いと思います。