我有一个Facelets页面,其中包含一个<h:dataTable>
。在每一行中都有一个<h:selectBooleanCheckbox>
。如果选中了复选框,则应将相应行后面的对象设置在bean中。
- 我该如何做到这一点?
- 如何在后备bean中获取所选行或其数据?
- 或者最好使用
<h:selectManyCheckbox>
吗?
我有一个Facelets页面,其中包含一个<h:dataTable>
。在每一行中都有一个<h:selectBooleanCheckbox>
。如果选中了复选框,则应将相应行后面的对象设置在bean中。
<h:selectManyCheckbox>
吗?您最好将<h:selectBooleanCheckbox>
的值与一个Map<Item, Boolean>
属性绑定,其中Item
表示相应行背后的对象。
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:selectBooleanCheckbox value="#{bean.checked[item]}" />
</h:column>
...
</h:dataTable>
<h:commandButton value="submit" action="#{bean.submit}" />
public class Bean {
private Map<Item, Boolean> checked = new HashMap<Item, Boolean>();
private List<Item> items;
public void submit() {
List<Item> selectedItems = checked.entrySet().stream()
.filter(Entry::getValue)
.map(Entry::getKey)
.collect(Collectors.toList());
checked.clear(); // If necessary.
// Now do your thing with selectedItems.
}
// ...
}
你看,这个Map会自动填充所有表格项作为键,复选框的值会自动设置为与该项作为键关联的Map值。
这仅要求 Item#equals()
和 Item#hashCode()
根据它们的契约正确实现。
如果无法保证,则最好使用一个Map<RowId, Boolean>
代替,其中RowId
表示行标识符的类型。让我们举一个例子,假设你有一个Item
对象,其标识符属性id
是一个Long
类型:
public class Item {
private Long id;
// ...
}
<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 Bean {
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
private List<Item> items;
public void submit() {
List<Item> selectedItems = items.stream()
.filter(item -> checked.get(item.getId()))
.collect(Collectors.toList());
checked.clear(); // If necessary.
// Now do your thing with selectedItems.
}
// ...
}
@Transient
private Long id;
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
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";
}
<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>
<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>
<Long,Item>
的Map
,只需迭代映射而不是整个列表,这样做难道不更容易吗? - user748187<h:selectBooleanCheckbox>
只支持boolean
或Boolean
值。 - BalusC