In my code, I have the following objects to implement a shopping cart:
public class CartItem {
...
public int id;
public int quantity;
...
}
public class Partner {
...
public List<CartItem> listOfItems;
...
}
public class Cart implements Serializable {
...
private List<Partner> listOfPartners;
...
}
In the ViewCart.xhtml page, I list the items as following:
...
<ui:repeat value="#{cartManagedBean.cart.listOfPartners}" var="p">
<ui:repeat value="#{p.listOfItems}" var="i">
<h:form>
...
<h:inputText size="3" value="#{i.quantity}" />
<h:commandButton value="Update" />
...
</h:form>
</ui:repeat>
</ui:repeat>
...
And this is my ManagedBean:
@ManagedBean
@SessionScoped
public class CartManagedBean {
...
private Cart cart;
...
}
All the getters and setters methods are properly done. Hence, I expected that when I click the update button, the quantity of the corresponding Item would be updated. However, when I test the function, only the last item in the list can be updated.
I’d be very grateful if someone could give me an advice on how I should tackle this problem.
UPDATE: I managed to make it work by replacing ui:repeat with h:dataTable. I think my knowledge of ui:repeat should be wrong somewhere. When I was using ui:repeat, I saw that the HTML generated was something like:
<form>
...
<input type="submit" id="jdt:51;jdt52" />
...
</form>
<form>
...
<input type="submit" id="jdt:51;jdt52" />
...
</form>
In other words, all the Items were generated with the same ID. I even tried to make the ID of the input for quantity unique by appending the unique ID of each item to the ID of the input as following:
<h:inputText id="quantity#{i.id}" size="3" value="#{i.quantity}" />
However, in the HTML result, I saw that the ID was something like:
<form>
...
<input type="submit" id="jdt:51;jdt52;quantity203" />
...
</form>
<form>
...
<input type="submit" id="jdt:51;jdt52;quantity203" />
...
</form>
In other words, the ID of the 1st Item was repeated for all subsequent items. Even though I haven’t fully understood how variables are updated with new values, I think this is the reason why only the last item can be updated.
I’d be very grateful if someone could explain this further for me so that I won’t make the same mistake again =).
You seem to be using Mojarra. The
<ui:repeat>is totally broken in Mojarra. I can reproduce your problem even on the latest Mojarra 2.1.4. It however works 100% when using MyFaces 2.1.3. I’ve reported it to the Mojarra guys as issue 2243.You have 3 options:
<c:forEach>instead of<ui:repeat>. This only works if the<c:forEach>is not by itself inside someUIDatacomponent.UIDatacomponent instead of<ui:repeat>.