-1

I have no idea why my forms behave in such way.

This is my JSF page:

<h:body>
  <h:form>
    <h:form>
      <h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
        <f:selectItems value="#{productBean.pizza}" var="pizza" itemValue="#{pizza}" itemLabel="#{pizza.name}" />
        <h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
    </h:form>
    <h:form>
      <h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
        <f:selectItems value="#{productBean.drink}" var="drink" itemValue="#{drink}" itemLabel="#{drink.name}" />
        <h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
    </h:form>
    <h:form>
      <h:selectOneMenu value="#{productBean.product}" converter="#{productConverter}" validator="com.jsf.ProductAvailableValidator">
        <f:selectItems value="#{productBean.other}" var="other" itemValue="#{other}" itemLabel="#{other.name}" />
        <h:commandButton value="Dodaj" action="#{productBean.addToOrder(productBean.product.name)}" /></h:selectOneMenu>
    </h:form>
    <messages />
    <h:outputText value="#{productBean.order}" />
    <h:commandButton value="Wyczyść" action="#{ProductBean.clearOrder()}" /></h:form>
</h:body>

And this is my ProductBean:

@ManagedBean
@SessionScoped
public class ProductBean extends Connector
{

    private List<Product> products;
    private List<Product> pizza;
    private List<Product> drink;
    private List<Product> other;
    boolean first = true;
    private StringBuilder order = new StringBuilder();

    public String getOrder() {
        return order.toString();
    }
    private Product product;

    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }
    public void addToOrder(String prod)
    {
        System.out.println("dodaje");
        if(first)
        {
            first = false;
            this.order.append(prod);  
        }
        else
            this.order.append(" + ").append(prod);
    }
    public void clearOrder()
    {
        this.order = null;
        first = true;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }
    public ProductBean() throws SQLException
    {
        resultSet = statement.executeQuery("SELECT * FROM dbo.products");
        products = new ArrayList<Product>();
        while(resultSet.next())
        {
            product = new Product();
            product.setId_product(resultSet.getInt("id_product"));
            product.setName(resultSet.getString("name"));
            product.setCategory(resultSet.getInt("category_id"));
            product.setIs_available(resultSet.getInt("is_available"));
            products.add(product);
        }
    }
    public Product getProductById(int id)
    {
        Iterator<Product> it = products.iterator();
        while(it.hasNext()) 
        {
            Product prod = it.next();
            if(prod.getId_product() == id)
                return prod;
        }
        return null;
    }

    public List<Product> getPizza() throws SQLException
    {   
        Iterator<Product> it = products.iterator();
        pizza = new ArrayList<Product>();
        while(it.hasNext()) 
        {
            Product prod = it.next();
            if(prod.getCategory() == 1)
                pizza.add(prod);
        }
        return pizza;
    }
    public List<Product> getDrink() throws SQLException
    {   
        Iterator<Product> it = products.iterator();
        drink = new ArrayList<Product>();
        while(it.hasNext()) 
        {
            Product prod = it.next();
            if(prod.getCategory() == 2)
                drink.add(prod);
        }
        return drink;
    }
    public List<Product> getOther() throws SQLException
    {   
        Iterator<Product> it = products.iterator();
        other = new ArrayList<Product>();
        while(it.hasNext()) 
        {
            Product prod = it.next();
            if(prod.getCategory() == 3)
                other.add(prod);
        }
        return other;
    }
    public List<Product> getProducts() {
        return products;
    }

}

I also send a screenshot here to make code easier and faster to analize: enter image description here

What happens here is that only the first button "Dodaj" (which means "add") works and add the String in outputlabel correctly. The rest of them do nothing. When I change the order, again only the first one works. Why?

MikO
  • 16,652
  • 11
  • 69
  • 103
Mateusz Gaweł
  • 671
  • 1
  • 6
  • 22
  • Nesting forms is forbidden in HTML and, therefore, is also forbidden in JSF. – skuntsel May 15 '13 at 16:06
  • what do u think is a good idea to mak it right? and works as i want – Mateusz Gaweł May 15 '13 at 16:29
  • Try to understand HTML syntax/HTML elements interaction better. In this particular case I'd do it all within one form with one order button and will AJAX-update components along the 'choosing way'. – skuntsel May 15 '13 at 16:35
  • adding the main nesting others inside was dumbest thing i ever do. Of course forms cannot be nested and i do know that. This was my whole problem, that one tag ruined my day. I know html/css better than JSF i think and the mistake was generated by the dark side of my brain;) @skuntsel If you mean what i think with the choosing. I dont expect to implement the delete button in order to cancel mistakes that can appear using onchange ajax + user. Maybe it's not good practice but i will stay with 3 separate forms i think. – Mateusz Gaweł May 15 '13 at 17:38

1 Answers1

1

You have multiple nested/cascaded <h:form>'s, that is not allowed in HTML! Either make one <h:form> and put all elements in that form, or make multiple <h:form>'s, but don't nest/cascade them!

Manuel
  • 3,481
  • 6
  • 30
  • 45
  • so how should I implemet such function in one form? I also need one main button to send the whole order String eventually – Mateusz Gaweł May 15 '13 at 16:07
  • use just one single `` around all of your JSF tags, it will do the job – Manuel May 15 '13 at 16:09
  • I did that and it's a mess right now. Every object from the list use verificator and without separate forms each button triggers validator for all selectOneMenus. For example I want to add only Coca-Cola but it won't let me beacause "Pudełko na wynos" is not available and validator can't make it pass – Mateusz Gaweł May 15 '13 at 16:20
  • You don't have the choice. You need to construct it in a way that avoids nesting forms. – skuntsel May 15 '13 at 16:29
  • -1: They're not nested ``s otherwise not even the first `` would have worked to begin with. – Luiggi Mendoza May 15 '13 at 16:59
  • By the way, I wrote an answer explaining all this but then I realized that I wasn't providing a real solution to the problem and a proper answer is too much to explain. Just to notice something: you're sending `productBean.product.name` as parameter in your `` action, which in this case is wrong. – Luiggi Mendoza May 15 '13 at 17:02
  • @LuiggiMendoza I didn't understand your downvote, as forms in fact are nested. Probably you meant that nested forms aren't the only big problem of the code given, like command button nested within dropdown box? – skuntsel May 15 '13 at 17:44
  • @skuntsel it's hard to read since OP's used a `` that wraps the others non-nested ``s or maybe that was a typo (since another person edited question content). Still, assuming the first `` wasn't there, the problem is not about nested forms. – Luiggi Mendoza May 15 '13 at 17:56
  • Well, actually when i removed that stupid form tag it worked as it's supposed to work. I did also what Luiggi suggested and removed commandbutton from selectonemenutag (why it's even there ?) I think i need some sleep – Mateusz Gaweł May 15 '13 at 18:50