2

I have an <ui:repeat> with <ui:inputText>:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"    
    xmlns:ui="http://java.sun.com/jsf/facelets"
    template="./templates/masterLayout.xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core">

    <ui:define name="content">
        <ui:repeat value="#{genproducts.dbList()}" var="itemsBuying">
            <div class="indproduct">
                <p class="center">#{itemsBuying.name}</p>
                <div class="center">
                    <h:form style="margin-left: auto; margin-right: auto;">
                        <h:inputText value="#{itemsBuying.amount}" />
                        <h:commandLink action="#{shoppingCart.addToCart(itemsBuying)}" value="add" />
                    </h:form>
                </div> 
            </div>
        </ui:repeat>
    </ui:define>
</ui:composition>

This is the #{genproducts} backing bean:

@ManagedBean(name = "genproducts")
@ViewScoped
public class Genproducts{

    public List<Product> dbList() throws SQLException {
        List<Product> list = new ArrayList<>();
        ...
        return list;
    }

} 

This is the Product entity:

@ManagedBean(name = "product")
@RequestScoped
public class Product {

    private int amount;

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

}

In my case, there are four products from dbList() method. For the first three products, when I input a different value, the default value appears in action method. Only for the last product, it works as expected.

How is this caused and how can I solve it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • With the code you have written each link is within its own form. Why are you using a form per link? Move the form outside the ui:repeat: – zargarf Jun 04 '13 at 10:30
  • Because there are many products, if I move the form outside the ui:repeat ,it won't work as expected. – user2449972 Jun 05 '13 at 13:50

1 Answers1

0

It's caused because you're (re)creating the list in the getter method behind <ui:repeat value>. This method is invoked during every iteration round. So, every next iteration will basically trash the values set during the previous iteration. In the action method, you end up with the list as created during the last iteration round. That's why the last entry seems to work fine.

This approach is indeed absolutely not right. You should not be performing business logic in getter methods at all. Make the list a property and fill it only once during bean's (post)construction.

@ManagedBean(name = "genproducts")
@ViewScoped
public class Genproducts{

    private List<Product> list;

    @PostConstruct
    public void init() throws SQLException {
        list = new ArrayList<>();
        // ...
    }

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

} 

Which is to be referenced as

<ui:repeat value="#{genproducts.list}" var="itemsBuying">

See also

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thanks BalusC, I use dbList() method because it will return different results according to user's choice. Also I wonder why the last product works as expected while others not. I tried with p:spinner and h:inputText, there wasn't any difference. With ui:repeat , I think each product in the list should work in the same way but it isn't. – user2449972 Jun 05 '13 at 14:01
  • You should manipulate the property in (post)constructor or action(listener) method, not in the property's getter method. Click the "See also" link to learn more. As to why the last product works, this is already explained in 1st paragraph of the answer. Did you read the text and the links of the answer as well instead of only the code? – BalusC Jun 05 '13 at 14:01