回答

48

最好的辦法是將h:selectBooleanCheckbox值與Map<RowId, Boolean>屬性其中RowId表示行標識符的類型綁定。讓我們看你已經一個Item對象,其標識屬性的示例idLong

<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作爲關鍵字,並且複選框值爲automati cally設置爲與項目id關聯的地圖值。

+0

使用''類型的'Map'不是更容易嗎,所以你只需要迭代地圖而不是整個列表? – 2011-05-11 07:29:10

+0

@Markus:那是不可能的。 ''只支持布爾值或布爾值。 – BalusC

+1

是數據表和按鈕應該是相同的形式?你可以請發表更多細節的觀點,或只有按鈕應在一種形式。 –

1

一個通過<h:selectBooleanCheckbox>在參數發送方式是通過複選框的標題送進去。在ValueChangeListener中,您可以使用getAttributes().get("title")從組件中獲取它。這有助於您想要將id值作爲參數發送(而不是所選行索引)。

+0

我不確定你的意思是「與選定的行索引相對」,但如果你的目標是我的答案,然後請注意,我無處傳遞行索引。只是所選項目本身的ID。 – BalusC

3

在下面的例子中,我使用複選框選擇兩個或更多的產品,讓用戶在產品規格使用JSF 2.0一個新的網頁上進行比較。

我花了很長時間才發現以下問題(當然完全顯而易見),所以認爲值得一提的是那些試圖使用分頁與BalusC的代碼上面(好的回答BalusC,比我想象的要簡單得多將會)。

如果使用分頁,你會得到在該行nullpointers:

如果(checked.get(item.getId()))

-in上述BalusC的代碼。

這是因爲只有顯示覆選框被添加到地圖(DOH;拍擊額)。 對於那些從未顯示覆選框的產品,由於分頁,此行將導致空指針錯誤,並且需要添加檢查以忽略這些空指針(假設所有複選框在頁面加載時均未選中)。爲了讓用戶勾選一個複選框,他們需要顯示分頁頁面,以便所有分頁都能很好地工作。

如果需要部分或全部的複選框上的第一個頁面加載被選中,那麼這將是沒有幫助到你...您將不得不手動將這些添加到地圖,以便在頁面加載時正確顯示它們。

注意:由於我使用的是JPA的'數據庫實體類'對象,我還需要在我的ProductTbl實體類中使用@Transient作爲id,因爲默認情況下所有變量都被JPA視爲數據庫中的列,除非以@Transient作爲前綴。此外,我正在使用第二個鏈接重置複選框,它調用clearSelections(),而我的「提交」是一個調用compareSelectedProducts()而不是提交按鈕的鏈接。

完整的代碼如下:

在從數據庫中得到的 'ProductTbl' Entity類:

@Transient 
private Long id; 

public Long getId() 
{ 
    return id; 
} 

public void setId(Long id) 
{ 
    this.id = id; 
} 

在背襯豆 '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> 
相關問題