JSFのテーブルに動的に行を追加するにはどうすればよいですか?
-
21-09-2019 - |
質問
私のアプリケーションでは、ボタンをクリックして行を追加する必要があり、このボタンはすべての行に含まれます。これを行うには助けが必要ですか?
アイテムクラス
public class Item {
public Item()
{
}
private String value;
public Item(String value) { this.value = value; }
public void setValue(String value) { this.value = value; }
public String getValue() { return value; }
}
Beanクラスの管理
public class MyMB
{
private List<Item> list;
public void addItem() { // JSF action method
list.add(new Item("Default"));
Iterator<Item> iterator = list.iterator();
while(iterator.hasNext())
{
Item item = (Item)iterator.next();
System.out.println(item.getValue());
}
System.out.println();
}
/**
* @return the list
*/
public List<Item> getList() {
if(list==null)
{
loadList();
}
return list;
}
private void loadList() {
list = new ArrayList<Item>();
list.add(new Item("Data"));
}
}
JSFコード
<h:form>
<rich:dataTable value="#{myMB.list}" var="item" id="tabel">
<h:column><h:inputText value="#{item.value}" /></h:column>
<h:column><a4j:commandButton value="Add" actionListener="#{myMB.addItem}" reRender="tabel"/></h:column>
解決
あなたがやらなければならないことは、基本的には確かにちょうどvalue
のh:dataTable
属性の背後にあるデータモデルに空のオブジェクトを追加しています。
しかし、同じ空の行も同様に後続の要求に保存する必要があります。バッキングBeanは、要求がスコープされた場合は、データモデルは、空の行せずにリロードされます。 Beanがセッションスコープの場合にこれがすべて動作するはずです。
さらに、あなたのJSFコード内のいくつかの誤りがあります。 h:dataTable
のvar
属性が不足していると、列の内容はh:column
内にする必要があります。
<h:form>
<h:dataTable value="#{bean.list}" var="item">
<h:column><h:inputText value="#{item.value}" /></h:column>
</h:dataTable>
<h:commandButton value="Add" action="#{bean.add}"/>
</h:form>
AのセッションまたはビューがスコープのBeanは次のように見ることができます:
public class Bean {
private List<Item> list;
public Bean() {
list = new ArrayList<Item>();
}
public void add() {
list.add(new Item());
}
public List<Item> getList() {
return list;
}
}
Item
クラスはもちろん、デフォルトの引数なしのコンストラクタを持つ必要があります。通常、これはすでに暗黙的に提供されていますが、引数を使用して独自のコンストラクタを定義した場合、それはもう利用できません。あなたは、そうでない場合は、あなたはもうItem item = new Item();
を行うことができない、明示的に定義する必要があります。
public class Item {
private String value;
public Item() {
// Keep default constructor alive.
}
public Item(String value) {
this.value = value;
}
// ...
}
あなたはののリクエストスコープでBeanを維持することを好む場合は、は、その後、あなたは、Beanが負荷に同じ量を維持することができるように、新しく追加されたアイテムの量を維持する必要があります。
public class Bean {
private List<Item> list;
private HtmlInputHidden count = new HtmlInputHidden();
public Bean() {
count.setValue(0);
}
public void add() {
list.add(new Item());
}
public List<Item> getList() {
if (list == null) loadList();
return list;
}
public HtmlInputHidden getCount() {
return count;
}
public void setCount(HtmlInputHidden count) {
this.count = count;
}
private void loadList() {
list = new ArrayList<Item>();
// Preserve list with newly added items.
for (int i = 0; i < (Integer) count.getValue(); i++) {
list.add(new Item());
}
}
}
あなたが唯一のJSFページの<h:form>
に以下を追加する必要があります:
<h:inputHidden binding="#{bean.count}" converter="javax.faces.Integer" />
あなたはこの記事が役に立つかもしれませんどのような方法でのDataTableを使用する方法の詳細については洞察: DataTable を使用します。また、リクエストやセッションスコープの両方の例の多くのWARファイルが含まれています。
他のヒント
例として、この表を取ります:
<h:datatable value="#{myBean.list}" ...>
...
<h:column>
<h:commandButton value="Add a row" action="#{myBean.addRow}"/>
</h:column>
</h:datatable>
方法のmyBean.addRow の単にあなたのリストに新しい要素を追加します。
public class MyBean {
private List<SomeClass> list;
...
public List<SomeClass> getList() {
return list;
}
public void addRow() {
list.add(new SomeClass());
}
}
あなたはボタンをクリックします場合は、、方法ののAddRow はのリストの中に新しい要素を追加します。ページが更新され、新しい行を持つテーブルを表示します。
の編集:の
あなたのポスト版、三つのことについて
のポイント1:?のあなたは、エラーのスタックトレースを添付してくださいでした。
のポイント2:のナビゲーションのためにJSFが使用するIDですString
を返すのAddRowあなたの方法。このアクションは、(同じページ上で、すなわちユーザーステー)任意のナビゲーションを必要としないため、単純にnull
または""
を返します:
public String addRow() {
list.add(new Item("new data"));
return null;
}
のポイント3:の私はあなたのクラスItem
は(あなたの現在のコンストラクタのほかに)空のコンストラクタを提供することを示唆している。
public Item() {
}