The Raven
The Raven

Reputation: 527

Dynamically setting value of a h:selectOneMenu using c:forEach

I'm working on a project that requires me to display and be able to select and store tags to the product. Tags are provided in tree-like structure. I can't assume maximum depth of a tags tree.

I wanted to display tags split by levels, using c:forEach - p:selectManyCheckbox - f:selectItems, and handling selections using p:ajax components.

I use following types to store possible values and selections in Tree object:

HashMap<Long, ArrayList<Tag>> tree;
HashMap<Long, Object[]> selected;

Hashmap keys are equal to "tag level".

In order to display values I use following code for testing:

<p:panelGrid id="tagDisplay" columns="2">
    <c:forEach begin="1" end="5" var="idx">
        <p:outputLabel value="#{idx}"></p:outputLabel>
        <p:selectManyCheckbox value="#{product.tags.selected[1]}">
            <f:selectItems value="#{product.tags.tree[1]}" var="tag" itemLabel="#{tag.name}" itemValue="#{tag.id}" />
            <p:ajax listener="#{product.selectorListener}" update="tagDisplay" />
        </p:selectManyCheckbox>
    </c:forEach>
</p:panelGrid>

Code seemed to work fine, though displayed five times.

Now I'm stuck trying to dynamically bind Hashmaps to selectors. As I replaced "1" with "idx", I got no results.

I tried to use ui-repeat with a dummy table, but then I lost panelgrid structure.

Any help will be appreciated!

My environment - Websphere 8.5, JSF 2.2, Primefaces 5.2

Upvotes: 0

Views: 815

Answers (1)

BalusC
BalusC

Reputation: 1108972

The <c:forEach begin end> is only for static iteration, not for dynamic iteration.

You'd better iterate over #{product.tags.tree} itself in <c:forEach items>. Each iteration over a Map will give Map.Entry back which in turn has getKey() and getValue() methods.

<p:panelGrid ...>
    <c:forEach items="#{product.tags.tree}" var="entry" varStatus="loop">
        <p:outputLabel value="#{loop.index}"></p:outputLabel>
        <p:selectManyCheckbox value="#{product.tags.selected[entry.key]}">
            <f:selectItems value="#{entry.value}" ... />
            ...
        </p:selectManyCheckbox>
    </c:forEach>
</p:panelGrid>

That said, must it really be a HashMap? Don't you rather want a fixed ordered LinkedHashMap?

Upvotes: 1

Related Questions