Come utilizzare in o per selezionare più voci?

Ho una pagina Facelets con . In ogni riga c’è un . Se la casella di controllo è selezionata, l’object dietro la riga corrispondente deve essere impostato nel bean.

  1. Come faccio a fare questo?
  2. Come ottenere le righe selezionate oi loro dati in un bean di supporto?
  3. O sarebbe meglio farlo con ?

La soluzione migliore è associare il valore h:selectBooleanCheckbox con una proprietà Map dove RowId rappresenta il tipo dell’identificatore di riga. Prendiamo ad esempio che hai un object Item cui id proprietà identificatore è un Long :

     ...   

che deve essere usato in combinazione con:

 public class Item { private Long id; // ... } 

e

 public class Bean { private Map checked = new HashMap(); private List items; public void submit() { List checkedItems = checked.entrySet().stream() .filter(Entry::getKey) .map(Entry::getValue) .collect(Collectors.toList()); checked.clear(); // If necessary. // Now do your thing with checkedItems. } // ... } 

Vedete, la mappa viene automaticamente riempita con l’ id di tutti gli elementi della tabella come chiave e il valore della casella di controllo viene automaticamente impostato come valore della mappa associato id object come chiave.

Nell’esempio seguente sto usando le checkbox per selezionare due o più prodotti per consentire all’utente di confrontare le specifiche del prodotto su una nuova pagina web usando JSF 2.0.

Mi ci è voluto un bel po ‘per trovare il seguente problema (assolutamente ovvio ora ovviamente) quindi ho pensato che valesse la pena menzionare coloro che cercano di usare la paginazione con il codice di BalusC sopra (bella risposta BalusC, molto più semplice di quanto avrei mai immaginato).

Se si utilizza l’impaginazione, si ottengono nullpointer sulla linea:

if (checked.get (item.getId ()))

-nel codice di BalusC sopra.

Questo perché solo le caselle di controllo visualizzate vengono aggiunte alla mappa (doh, fronte slap). Per i prodotti le cui caselle di controllo non vengono mai visualizzate, a causa dell’impaginazione, questa riga genererà un errore puntatore nullo e sarà necessario aggiungere un controllo per ignorare questi puntatori nulli (presupponendo che tutte le caselle di controllo siano deselezionate al caricamento della pagina). Per consentire all’utente di spuntare una casella di controllo, è necessario visualizzare la pagina di impaginazione, quindi tutto funziona bene lì dopo.

Se alcune o tutte le caselle di controllo devono essere spuntate sul primo caricamento della pagina, questo non ti sarà di alcun aiuto … dovrai aggiungerle manualmente alla Mappa per farle visualizzare correttamente al caricamento della pagina .

Nota: poiché sto utilizzando un object JPA ‘Entity class from database’ ho anche dovuto usare @Transient per l’id nella mia class entity framework ProductTbl poiché tutte le variabili sono considerate colonne nel database da JPA, per impostazione predefinita, a meno che non sia preceduto da @Transient . Inoltre sto usando un secondo link per reimpostare le caselle di controllo, che chiama clearSelections (), e il mio ‘submit’ è un link che chiama compareSelectedProducts () piuttosto che un pulsante Submit.

Il codice completo è il seguente:

Nella class Entity ‘ProductTbl’ derivata dal database:

 @Transient private Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } 

Nel bean di supporto “ProductSelection”:

 private Map checked = new HashMap(); private String errorMessage = ""; // List of all products. private List products; // List of products to compare. private List 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"; } 

Nella pagina Web JSF “MainSearchResult.xhtml”:

        

Nel file “faces-config.xml”:

   process_MainSearchResult /MainSearchResult.xhtml     process_CompareSelected /CompareSelected.xhtml     process_ErrorPage /ErrorPage.xhtml   

Un modo per inviare un parametro tramite è inviarlo tramite il titolo della casella di controllo. In ValueChangeListener , puoi ottenerlo dal componente usando getAttributes().get("title") . Ciò aiuta nei casi in cui si desidera inviare un valore id come parametro (in contrapposizione all’indice riga selezionato).