Alex Rivera | Logout

How to use <h:selectBooleanCheckbox> in <h:dataTable> or <ui:repeat> to select multiple items?

Asked 2010-03-26T15:42:31.500
21

I have a Facelets page with a <h:dataTable>. In each row there is a <h:selectBooleanCheckbox>. If the checkbox is selected the object behind the corresponding row should be set in the bean.

  1. How do I do this?
  2. How to get the selected rows or their data in a backing bean?
  3. Or would it be better to do it with <h:selectManyCheckbox>?
Edit
Report

1 Answer

53

Your best bet is to bind the <h:selectBooleanCheckbox> value with a Map<Item, Boolean> property where Item represents the object behind the corresponding row.

<h:dataTable value="#{bean.items}" var="item">
    <h:column>
        <h:selectBooleanCheckbox value="#{bean.checked[item]}" />
    </h:column>
    ...
</h:dataTable>
<h:commandButton value="submit" action="#{bean.submit}" />
public class Bean {
    private Map<Item, Boolean> checked = new HashMap<Item, Boolean>();
    private List<Item> items;

    public void submit() {
        List<Item> selectedItems = checked.entrySet().stream()
            .filter(Entry::getValue)
            .map(Entry::getKey)
            .collect(Collectors.toList());

        checked.clear(); // If necessary.

        // Now do your thing with selectedItems.
    }

    // ...
}

You see, the map is automatically filled with all table items as key and the checkbox value is automatically set as map value associated with the item as key.

This only requires that the Item#equals() and Item#hashCode() is properly implemented as per their contracts.

If you can't guarantee that, then you'd better use a Map<RowId, Boolean> instead where RowId represents the type of the row identifier. Let's take an example that you've a Item object whose identifier property id is a Long:

public class Item {
    private Long id;
    // ...
}
                            answered 2010-03-26T16:18:32.003
                            
                        

Your Answer