.を持つ Facelets ページがあり<h:dataTable>
ます。各行には があり<h:selectBooleanCheckbox>
ます。チェックボックスが選択されている場合、対応する行の背後にあるオブジェクトを Bean に設定する必要があります。
- どうすればいいですか?
- 選択した行またはそのデータをバッキング Bean で取得する方法は?
- それとも でやったほうがいい
<h:selectManyCheckbox>
ですか?
.を持つ Facelets ページがあり<h:dataTable>
ます。各行には があり<h:selectBooleanCheckbox>
ます。チェックボックスが選択されている場合、対応する行の背後にあるオブジェクトを Bean に設定する必要があります。
<h:selectManyCheckbox>
ですか?あなたの最善の策は、行識別子のタイプを表すプロパティにh:selectBooleanCheckbox
値をバインドすることです。識別子プロパティが であるオブジェクトがある例を見てみましょう:Map<RowId, Boolean>
RowId
Item
id
Long
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:selectBooleanCheckbox value="#{bean.checked[item.id]}" />
</h:column>
...
</h:dataTable>
<h:commandButton value="submit" action="#{bean.submit}" />
以下と組み合わせて使用します。
public class Item {
private Long id;
// ...
}
と
public class Bean {
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private List<Item> items;
public void submit() {
List<Item> checkedItems = checked.entrySet().stream()
.filter(Entry::getKey)
.map(Entry::getValue)
.collect(Collectors.toList());
checked.clear(); // If necessary.
// Now do your thing with checkedItems.
}
// ...
}
ご覧のとおり、マップにはid
すべてのテーブル項目がキーとして自動的に入力され、チェックボックスの値は項目に関連付けられたマップ値id
としてキーとして自動的に設定されます。
次の例では、チェックボックスを使用して 2 つ以上の製品を選択し、ユーザーが JSF 2.0 を使用して新しい Web ページで製品仕様を比較できるようにしています。
次の問題を見つけるのにかなりの時間がかかりました(もちろん今では完全に明白です)ので、上記のBalusCのコードでページネーションを使用しようとしている人にとっては言及する価値があると思いました(いい答えBalusC、私が想像していたよりもはるかに簡単です)。
ページネーションを使用している場合、次の行で nullpointers が取得されます。
if (checked.get(item.getId()))
-上記のBalusCのコード。
これは、表示されたチェック ボックスのみがマップに追加されるためです (doh; 平手打ち)。ページネーションのためにチェック ボックスが表示されない製品の場合、この行はヌル ポインター エラーになり、これらのヌル ポインターを無視するためにチェックを追加する必要があります (ページの読み込み時にすべてのチェック ボックスがオフになっていると仮定します)。ユーザーがチェックボックスをオンにするには、ページネーションページを表示して、その後すべてがうまく機能するようにする必要があります。
最初のページの読み込み時に一部またはすべてのチェック ボックスをオンにする必要がある場合、これは役に立ちません。ページの読み込み時に正しく表示されるようにするには、それらを手動でマップに追加する必要があります。 .
注: JPA 'データベースからのエンティティ クラス' オブジェクトを使用しているため、ProductTbl エンティティ クラスの id に @Transient を使用する必要がありました。これは、@Transient のプレフィックスが付いていない限り、すべての変数がデフォルトで JPA によってデータベースの列と見なされるためです。 . また、clearSelections() を呼び出すチェック ボックスをリセットする 2 つ目のリンクを使用しています。私の「送信」は、送信ボタンではなく、compareSelectedProducts() を呼び出すリンクです。
完全なコードは次のとおりです。
データベースから派生した 'ProductTbl' エンティティ クラス:
@Transient
private Long id;
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
バッキング Bean 'ProductSelection' で:
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private String errorMessage = "";
// List of all products.
private List<ProductTbl> products;
// List of products to compare.
private List<ProductTbl> compareProducts;
// Setters and getters for above...
public String compareSelectedProducts()
{
// Reset selected products store.
compareProducts = new ArrayList();
for (ProductTbl item: products)
{
// If there is a checkbox mapping for the current product then...
if(checked.get(item.getId()) != null)
{
// If checkbox is ticked then...
if (checked.get(item.getId()))
{
// Add product to list of products to be compared.
compareProducts.add(item);
}
}
}
if(compareProducts.isEmpty())
{
// Error message that is displayed in the 'ErrorPage.xhtml' file.
errorMessage = "No Products selected to compare specifications. Select two or more products by ticking the check box in the second column 'Cmpr'";
return "process_ErrorPage";
}
// Rest of code to get product specification data ready to be displayed.
return "process_CompareSelected";
}
public String clearSelections()
{
// Untick all checkbox selections.
checked.clear();
return "process_MainSearchResult";
}
JSF Web ページ 'MainSearchResult.xhtml':
<h:commandLink action="#{productSelection.compareSelectedProducts()}" value="Cmpr Specification Comparison Table" />
<h:commandLink action="#{productSelection.clearSelections()}" value="Clear Selected" />
<h:dataTable value="#{productSelection.products}" rows="#{productSelection.numberRowsToDisplay}" first="#{productSelection.rowStart}" var="item" headerClass="table-header" >
<h:column>
<f:facet name="header">
<h:outputText style="font-size:12px" value="Cmpr" />
</f:facet>
<div style="text-align:center;" >
<h:selectBooleanCheckbox value="#{productSelection.checked[item.id]}" />
</div>
</h:column>
</h:dataTable>
「faces-config.xml」ファイル内:
<navigation-rule>
<navigation-case>
<from-outcome>process_MainSearchResult</from-outcome>
<to-view-id>/MainSearchResult.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>process_CompareSelected</from-outcome>
<to-view-id>/CompareSelected.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<navigation-case>
<from-outcome>process_ErrorPage</from-outcome>
<to-view-id>/ErrorPage.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
パラメーターを送信する 1 つの方法<h:selectBooleanCheckbox>
は、チェックボックスのタイトルを介して送信することです。では、ValueChangeListener
を使用してコンポーネントから取得できますgetAttributes().get("title")
。これは、(選択した行インデックスではなく) id 値をパラメーターとして送信する場合に役立ちます。