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

Javaで主にシステム開発をしながら思うところをツラツラを綴る。主に自分向けのメモ。EE関連の情報が少なく自分自身がそういう情報があったら良いなぁということで他の人の参考になれば幸い

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
「選択無し」を選択したら、お菓子リストがクリアされました。
今回は初期リストは空ですが、何かしら意味のあるリストを設定しても良いと思います。

Code

2018/4/17 追加

Bitbucket