views:

28

answers:

1

Hi folks,

The h:selectBooleanCheckbox in question is in a h:dataTable (of Extras) within a h:dataTable (of Items) within a h:dataTable (of Categories). Many Items are displayed and each Item can have many Extras.

<h:dataTable value="#{bean.categoryList}" var="category">
    <h:column>
        <h:dataTable value="#{category.itemList}" var="item">
            <h:column>
                <h:dataTable value="#{item.extraList}" var="extra">
                    <h:column>
                        <!-- The h:selectBooleanCheckbox in question //-->
                        <h:selectBooleanCheckbox value="#{bean.extraSelectedMap[item.id][extra.id]}"/>
                    </h:column>
                    <h:commandLink action="#{bean.add}" value="Add">
                </h:dataTable>
            </h:column>
        </h:dataTable>
    </h:column>
</h:dataTable>

After the page is rendered I select a check box then select 'Add'. Inside bean.add my

Map<Integer, HashMap<Integer, Boolean>>

has an empty HashMap when I am expecting it to have the id of the extra mapped to the value true.

What is incorrect with the code, or the entire approach, above?

Many thanks and regards.

A: 

First, your h:dataTable is three levels deep. If you want to attach the checkbox to a parent managed bean property, then you need to take all levels into account. So,

<h:selectBooleanCheckbox value="#{bean.extraSelectedMap[category.id][item.id][extra.id]}"/>

with a Map<Integer, Map<Integer, Map<Integer, Boolean>>> as property. Otherwise the selections will be overridden for every category until the selected items of the last category ends up in the map.

Second, you need to precreate the map and all nested maps as well. JSF won't do that for you. In other words,

public Bean() {
    extraSelectedMap = new HashMap<Integer, Map<Integer, Map<Integer, Boolean>>>();
    for (Category category : categoryList) {
        Map<Integer, Map<Integer, Boolean>> selectedExtrasPerCategory = new HashMap<Integer, Map<Integer, Boolean>>();
        extraSelectedMap.put(category.getId(), selectedExtrasPerCategory);
        for (Item item : category.getItemList()) {
            Map<Integer, Boolean> selectedExtrasPerItem = new HashMap<Integer, Boolean>();
            selectedExtrasPerCategory.put(item.getId(), selectedExtrasPerItem);
        }
    }

As an alternative, you can also consider to just add a Boolean property to Extra and bind to that instead.

BalusC