JSF: value bindings inside nested ui: repeat

I have a strange problem with the <ui:repeat> . Even for my very simple example, value bindings inside nested repeat components do not work as expected.

I have a simple simple view:

 <h:body> <h:form> <ui:repeat value="#{sandbox.rows}" var="row"> <ui:repeat value="#{row.columns}" var="column"> <h:outputText value="#{column.value}" /> <h:selectBooleanCheckbox value="#{column.value}" /> </ui:repeat> <br/> </ui:repeat> <h:commandButton action="#{sandbox.refresh}" value="Refresh" /> </h:form> </h:body> 

and Sandbox class:

 @Component @Scope("request") public class Sandbox { public static class Row { private List<Column> columns = Arrays.asList(new Column(), new Column()); public List<Column> getColumns() { return columns; } } public static class Column { private boolean value; public void setValue(boolean value) { this.value = value; } public boolean getValue() { return this.value; } } public List<Row> rows = Arrays.asList(new Row(), new Row()); public List<Row> getRows() { return rows; } public void refresh() { rows.get(0).getColumns().get(0).setValue(true); System.err.println("refresh clicked"); } } 

So, my larva goes over the β€œrows” in the sandbox, in which there are several β€œcolumns”, each of which has a meaning. For each such column, a value is printed and <h:selectBooleanCheckbox> with the value associated with it.

When I load the page, all values ​​are displayed as false and all checkboxes are not checked. Now click refresh should change the value of the first column of the first row to true. However, I get the following output:

  true [] false []
 false [] false []

In other words, <h:outputText> displays it as true, but the checkbox is not . Of course, I am allowed to change the model at the stage of the application-application, and what should be reflected in the visualization of the view?

If I remove one level of nesting, that is, only one <ui:repeat> , everything works as expected: the checkbox is checked and the value is displayed as true. So it looks like this is related to the UIRepeat component. In fact, it looks like UIRepeat has special handling when it is nested in another UIRepeat.

From what I am compiling, UIRepeat essentially repeats the same component several times. Between each visualization call, it loads a β€œstate” (value, localValue, submittedValue) of all child components that implement the EditableValueHolder from the internal map (with the key to the actual component identifier). I tried to set breakpoints when this happens to keep track of which value is inserted into the saved state map, but this is really a mess, as the saveChildState and restoreChildState methods are called in about milliseconds.

Any ideas? Can I do otherwise? I really need to display a table dynamically growing both horizontally and vertically, containing checkboxes, input fields, etc. I took a look at <h:dataTable> , but I believe that this will not work in this case.

+4
source share
1 answer

An interesting problem. I can reproduce this with Mojarra 2.0.3. This is definitely the problem of maintaining the state of ui:repeat . I reported this as a question to 1807 guys Mojarra. It works fine when the outer loop is c:forEach .

+6
source

All Articles