LoginSignup
11
10

More than 1 year has passed since last update.

JSFでループで生成した入力項目をバッキングBeanのプロパティとマッピングする方法

Last updated at Posted at 2014-03-05

バッキングBean が List のプロパティを持っていたとする。

これを、 xhtml 上でループを回しながら出力するのは簡単だけど、入力項目としてマッピングするにはどうすればいいのか、簡単にはわからなかったのでメモ。

2021-11-15 追記

  • 上記 Stackoverflow によると、 ui:repeat は view tree が構築されたあとに処理されるのに対して、パラメータの処理は view tree の構築中に処理されるという違いがあり、それが原因でバインドができないらしい
  • <c:forEach> でループさせれば、かなり簡潔に書けるもよう
  • ただし、試してみたところバッキングビーンは @ViewScoped である必要があった(@RequestScoped だと、パラメータが渡せなかった)

環境

AP サーバー

GlassFish 3.1.2.2

実装

KeyValue.java
package sample.jsf;

public class KeyValue {
    private String key;
    private String value;

    public KeyValue(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "KeyValue [key=" + key + ", value=" + value + "]";
    }
}
HelloBean.java
package sample.jsf;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class HelloBean {

    private List<KeyValue> list;

    public void method() {
        System.out.println(this.list);
    }

    @PostConstruct
    public void init() {
        this.list = new ArrayList<>();
        this.list.add(new KeyValue("hoge", "HOGE"));
        this.list.add(new KeyValue("fuga", "FUGA"));
        this.list.add(new KeyValue("piyo", "PIYO"));
    }

    public void setList(List<KeyValue> list) {
        this.list = list;
    }

    public List<KeyValue> getList() {
        return list;
    }
}
hello.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:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
  <head>
    <title>index</title>
  </head>
  <body>
    <form jsfc="h:form">
      <div jsfc="ui:repeat" value="#{helloBean.list}" varStatus="loop">
        key:<input jsfc="h:inputText" value="#{helloBean.list[loop.index].key}" />
        value:<input jsfc="h:inputText" value="#{helloBean.list[loop.index].value}" />
      </div>
      <input jsfc="h:commandButton" action="#{helloBean.method}" value="submit" type="submit" />
    </form>
  </body>
</html>

入力項目(h:inputText)の value 属性で値を指定するときに、インデックス値で指定すれば、入力もうまくマッピングできるようになる。

以下のようにしてしまうと、入力のマッピングは動作しなくなる。

ダメパターン
<div jsfc="ui:repeat" value="#{helloBean.list}" var="item">
  key:<input jsfc="h:inputText" value="#{item.key}" />
  value:<input jsfc="h:inputText" value="#{item.value}" />
</div>

動作確認

初期表示

jsf_list_input_01.png

値を編集してサブミット

jsf_list_input_02.png

サブミット時の標準出力

情報: [KeyValue [key=aaa, value=AAA], KeyValue [key=bbb, value=BBB], KeyValue [key=ccc, value=CCC]]

ちゃんと入力した値がわたっている。

参考

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10