En el siguiente ejemplo estoy usando casillas de verificación para seleccionar dos o más productos para permitir al usuario comparar las especificaciones del producto en una nueva página web usando JSF 2.0.
Me tomó un buen tiempo encontrar el siguiente problema (totalmente obvio ahora por supuesto) así que pensé que merecía una mención para aquellos que intentaban usar la paginación con el código de BalusC (respuesta agradable BalusC, mucho más simple de lo que jamás imaginé sería).
Si está utilizando la paginación obtendrá nullpointers en la línea de:
si (checked.get (item.getId()))
-en código de BalusC anteriormente.
Esto se debe a que solo se agregan casillas de verificación al Mapa (doh; frente abofeteada). Para aquellos productos cuyas casillas de verificación nunca se muestran, debido a la paginación, esta línea generará un error de puntero nulo y se debe agregar una verificación para ignorar estos punteros nulos (suponiendo que todas las casillas de verificación estén desmarcadas en la carga de la página). Para que el usuario marque una casilla de verificación, entonces necesita mostrar la página de paginación para que todo funcione bien allí después.
Si algunas o todas las casillas de verificación deben marcarse en la carga de la primera página, esto no será de ninguna utilidad ...tendrá que agregarlos manualmente al Mapa para que se muestren correctamente en la carga de la página.
Nota: como utilizo un objeto JPA 'clase de entidad de la base de datos' también necesitaba usar @Transient para el ID en mi clase de entidad ProductTbl ya que todas las variables se consideran columnas en la base de datos por JPA, a menos que prefijado con @Transient. También estoy usando un segundo enlace para restablecer las casillas de verificación, que llama a clearSelections(), y mi 'submit' es un enlace que llama compareSelectedProducts() en lugar de un botón Enviar.
El código completo es el siguiente:
En la clase 'ProductTbl' Entidad derivado de la base de datos:
@Transient
private Long id;
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
En el 'ProductSelection' bean de respaldo:
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";
}
En la página web de 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>
En el archivo '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>
Hola BalusC, esto no está trabajando en la paginación, cualquier indicio? –