在以下示例中,我使用复选框来选择两个或多个产品,以允许用户使用 JSF 2.0 在新网页上比较产品规格。
我花了很长时间才找到以下问题(当然现在很明显)所以认为对于那些尝试使用上面的 BalusC 代码使用分页的人来说值得一提(很好的答案 BalusC,比我想象的要简单得多是)。
如果您使用分页,您将在该行获得空指针:
if (checked.get(item.getId()))
-在上面 BalusC 的代码中。
这是因为只有显示的复选框才会添加到地图中(doh;拍前额)。
对于那些复选框从不显示的产品,由于分页,此行将导致空指针错误,需要添加一个检查以忽略这些空指针(假设在页面加载时所有复选框都未选中)。为了让用户勾选一个复选框,他们需要显示分页页面,以便之后一切正常。
如果需要在第一个页面加载时勾选部分或全部复选框,那么这对您没有帮助...您必须手动将它们添加到地图中才能正确显示在页面加载时。
注意:因为我使用的是 JPA '来自数据库的实体类' 对象,所以我还需要在我的 ProductTbl 实体类中使用 @Transient 作为 ID,因为默认情况下,所有变量都被 JPA 视为数据库中的列,除非有前缀与@Transient。此外,我正在使用第二个链接来重置复选框,该链接调用 clearSelections(),我的“提交”是调用 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 网页'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>