wrschneider
wrschneider

Reputation: 18770

JSF h:selectBooleanCheckbox inside ui:repeat - varStatus.index works, var doesn't

Can someone please explain this phenomenon?

I am using Mojarra 2.1.6 - Glassfish 3.1.2.

I have a checkbox inside a ui:repeat. The ui:repeat is looping over a list of booleans from my managed bean. Each individual checkbox is bound to an element of that list. For example:

<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
  <h:selectBooleanCheckbox value="#{checkbox}"/>
</ui:repeat>

The problem is the values aren't getting applied to the managed bean. When I submit and re-render the form, the values don't stick.

However, if I index into the managed bean element explicitly, by changing value=#{checkbox} above to value="#{checkboxTestBean.list[status.index]}", everything works.

Any ideas why that might be the case?

XHTML:

<h:form>
<div>
Using value="#\{var\}"
<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
    <h:selectBooleanCheckbox value="#{checkbox}"/>
</ui:repeat>
</div>

<div>
Using value="#\{varStatus.index\}"
<ui:repeat var="checkbox" value="#{checkboxTestBean.list}" varStatus="status">
    <h:selectBooleanCheckbox value="#{checkboxTestBean.list[status.index]}"/>
</ui:repeat>
</div>
<h:commandLink actionListener="#{checkboxTestBean.actionListener}">
PROCESS FORM
    <f:ajax execute="@form" render="@form"/>
</h:commandLink>
</h:form>

Java:

@ManagedBean
@ViewScoped
public class CheckboxTestBean {

public List<Boolean> list = new ArrayList<Boolean>();

public CheckboxTestBean() {
    for (int i = 0; i < 5; i++) {
        list.add(Boolean.FALSE);
    }
}

public void actionListener(ActionEvent evt) {
    System.out.println("*** dumping whole form");
    System.out.println("*** list = " + list);
}

public List<Boolean> getList() {
    return list;
}

public void setList(List<Boolean> list) {
    this.list = list;
}
}

Upvotes: 3

Views: 6392

Answers (1)

BalusC
BalusC

Reputation: 1108642

That's because the Boolean as being an immutable class doesn't have a setter method for the value. When referencing it as a list item by index instead, EL will be able to set the new value on the List by index like so list.add(status.index, newValue). An alternative is to make it a property of a mutable model class and have a collection of it instead like so List<Item> which you reference by <h:selectBooleanCheckbox value="#{item.checkbox}"/>.

This is not specifically related to Boolean, you would have exactly the same problem when using for example List<String> in an <ui:repeat><h:inputText>.

See also:

Upvotes: 4

Related Questions