Reputation: 17337
I've two pieces of code, one that work and one that doesn't. I'm accessing accessing different objects in from a list in different selectOneMenu
. So if my list is of size 4 then I have 4 selectOneMenu
. There is a spinner
above the selectOneMenu
's to notify how many of them I want.
I don't understand why the first one using varstatus
to access a list works and the second one which use the var doesn't. A Map
is a custom entity btw.
Works :
<p:spinner value="#{matchCreation.numbreOfmaps}" min="1" max="7">
<f:ajax event="change" render="mapsGroup" execute="mapsGroup"/>
</p:spinner>
<!-- maps start -->
<h:panelGroup id="mapsGroup">
<table>
<ui:repeat var="mapPlayed" value="#{matchCreation.playedMaps}" varStatus="status">
<tr><td>
<p:selectOneMenu value="#{matchCreation.playedMaps[status.index]}">
<f:selectItems value="#{matchCreation.mapList}" var="map" itemValue="#{map}" itemLabel="#{map.name}"/>
<f:converter binding="#{mapConverter}"/>
</p:selectOneMenu>
</td></tr>
</ui:repeat>
</table>
</h:panelGroup>
Does NOT work :
<p:spinner value="#{matchCreation.numbreOfmaps}" min="1" max="7">
<f:ajax event="change" render="mapsGroup" execute="mapsGroup"/>
</p:spinner>
<!-- maps start -->
<h:panelGroup id="mapsGroup">
<table>
<ui:repeat var="mapPlayed" value="#{matchCreation.playedMaps}">
<tr><td>
<p:selectOneMenu value="#{mapPlayed}">
<f:selectItems value="#{matchCreation.mapList}" var="map" itemValue="#{map}" itemLabel="#{map.name}"/>
<f:converter binding="#{mapConverter}"/>
</p:selectOneMenu>
</td></tr>
</ui:repeat>
</table>
</h:panelGroup>
In this one the list will contain the number of map specified but they will all be equal to mapList.get(0)
.
java:
private List<Map> mapList; // initiated in post construct.
private List<Map> playedMaps;
private int numbreOfmaps = 1;
public List<Map> getPlayedMaps() {
// I know this is not advised but I didn't really think of another way.
// It's not heavy work anyway.
while (playedMaps.size() > numbreOfmaps) {
playedMaps.remove(playedMaps.size() - 1);
}
while (playedMaps.size() < numbreOfmaps) {
playedMaps.add(mapList.get(0));
}
return playedMaps;
}
Upvotes: 0
Views: 1114
Reputation: 1108742
<ui:repeat var="mapPlayed">
represents a scoped variable, not a bean property. To imagine the "under the covers" working, it look like:
for (Map mapPlayed : matchCreation.getPlayedMaps()) {
// ...
System.out.println(mapPlayed);
}
When using <p:selectOneMenu value="#{mapPlayed}">
, JSF actually sets the submitted value in the scoped variable, not the bean property. Under the covers, imagine it like:
for (Map mapPlayed : matchCreation.getPlayedMaps()) {
Map newMapPlayed = getSubmittedValueSomehow();
mapPlayed = newMapPlayed;
// ...
}
This doesn't get reflected in the list.
With the loop index it works better:
for (int index = 0; index < matchCreation.getPlayedMaps().size(); index++)
Map newMapPlayed = getSubmittedValueSomehow();
matchCreation.getPlayedMaps().set(index, newMapPlayed);
// ...
}
Unrelated to the concrete problem, shadowing names of standard Java SE API classes like Map
(from java.util.Map
) is a terribly bad idea.
Upvotes: 1