19

У меня есть страница Facelets с <h:dataTable>. В каждой строке есть <h:selectBooleanCheckbox>. Если флажок установлен, объект, расположенный за соответствующей строкой, должен быть установлен в компоненте.Как использовать <h: selectBooleanCheckbox> в <h:dataTable> или <ui:repeat> для выбора нескольких элементов?

  1. Как это сделать?
  2. Как получить выбранные строки или их данные в фоновом режиме?
  3. Или было бы лучше сделать это с помощью <h:selectManyCheckbox>?
+0

Привет BalusC, Это не работает на пагинацией, любой намек? –

ответ

48

Лучше всего, чтобы связать значение h:selectBooleanCheckbox с Map<RowId, Boolean> собственности, где RowId представляет тип идентификатора строки. Давайте рассмотрим пример, который у Вас есть Item объект, идентификатор свойство id является Long:

<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 всех элементов таблицы в качестве ключа, а значение флажка - автоматически как значение карты, связанное с элементом id как ключ.

+0

Не было бы еще проще использовать 'Map' типа' ', поэтому вам нужно будет только перебирать карту, а не весь список? – 2011-05-11 07:29:10

+0

@Markus: это невозможно. '' поддерживает только значения 'boolean' или' Boolean'. – BalusC

+1

- таблица данных, и кнопка должна быть в том же виде? можете ли вы отправить более подробную информацию для просмотра, или только кнопка должна быть в форме. –

1

Один из способов отправки параметра через <h:selectBooleanCheckbox> - отправить его через заголовок флажка. В ValueChangeListener вы можете получить его из компонента с помощью getAttributes().get("title"). Это помогает в случаях, когда вы хотите отправить значение id в качестве параметра (в отличие от выбранного индекса строки).

+0

Я не уверен, что вы имеете в виду под «в отличие от выбранного индекса строки», но если вы ориентируетесь на мой ответ, а затем обратите внимание, что я нигде не пропускаю индексы строк. Только идентификаторы выбранных элементов. – BalusC

3

В следующем примере я использую флажки для выбора двух или более продуктов, позволяющих пользователю сравнивать спецификации продукта на новой веб-странице с использованием JSF 2.0.

Мне потребовалось некоторое время, чтобы найти следующую проблему (совершенно очевидно, конечно, конечно), поэтому подумал, что стоит упомянуть тех, кто пытается использовать разбиение на страницы с кодом BalusC выше (хороший ответ BalusC, намного проще, чем я когда-либо себе представлял было бы).

Если вы используете пагинацию вы получите nullpointers на линии:

если (checked.get (item.getId()))

-в код BalusC в выше.

Это потому, что на карту добавлены только отображаемые флажки (doh; slap лба). Для тех продуктов, чьи флажки никогда не отображаются, из-за разбиения на страницы эта строка приведет к ошибке с нулевым указателем и должна быть добавлена ​​проверка, чтобы игнорировать эти нулевые указатели (при условии, что все флажки не отмечены при загрузке страницы). Для того, чтобы пользователь установил галочку, необходимо отобразить страницу разбиения на страницы, чтобы после этого все хорошо работало.

Если для загрузки первой страницы требуются некоторые или все флажки, то это не поможет вам ...вам придется вручную добавить их на Карту, чтобы они отображались правильно при загрузке страницы.

Примечание: поскольку я использую объект класса Entity класса из базы данных JPA, мне также необходимо использовать @Transient для идентификатора в моем классе Entity Entity, поскольку все переменные считаются столбцами в базе данных JPA, по умолчанию, если с префиксом @Transient. Также я использую вторую ссылку для сброса флажков, которая вызывает clearSelections(), а мой 'submit' - это ссылка, вызывающая compareSelectedProducts(), а не кнопку Submit.

Полный код выглядит следующим образом:

В Entity класса 'ProductTbl', полученных из базы данных:

@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> 

В файле 'лица-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> 
Смежные вопросы