バッキング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>
##サブミット時の標準出力
情報: [KeyValue [key=aaa, value=AAA], KeyValue [key=bbb, value=BBB], KeyValue [key=ccc, value=CCC]]
ちゃんと入力した値がわたっている。
#参考