Question

I have two instances of selectOneListbox which reference to the same property in a managed bean. Both lists belong to different forms.

When after selecting position in one of the lists, I choose the one in another, it is not getting selected, only for the first time; further selections are all fine.

Please advice how to solve the problem.

JSF

    <h:form>
            <ul style="list-style: none">
                <li>
                    <h:selectOneListbox size="1" value="#{adminController.model}" > 
                        <f:ajax event="valueChange" render="@all"/>
                        <f:selectItems value="#{adminController.gtSelectItem()}" var="p" itemValue="${p.name}" itemLabel="${p.name}"/>
                    </h:selectOneListbox>     
                </li>    
            </ul>
        </h:form>
        <h:form>
            <ul>
                <li>  
                    <h:selectOneListbox size="1" value="#{adminController.model}" > 
                        <f:ajax event="valueChange" render="@all"/>
                        <f:selectItems value="#{adminController.gtSelectItem()}" var="p" itemValue="${p.name}" itemLabel="${p.name}"/>
                    </h:selectOneListbox>     
                </li>   
                <h:commandButton value="Print">
                    <f:ajax event="click" listener="#{adminController.printAjax()}"/>
                </h:commandButton>
            </ul>

        </h:form>
    </div>

Managed Bean property

public String getModel() {
    return model;
}

public void setModel(String model) {
    this.model = model;
}

SelectItems

public ArrayList<Product> gtSelectItem() {
    ArrayList<Product> als = new ArrayList<>(pc.getProductList());
    return als;
}
Was it helpful?

Solution

You have many things to solve there. First of all, getter and setter prefixes are not written when using EL. Just use value="#{adminController.selectItem}" when you've a property to read/write. Your provided code is mistyped and ul and li tags are not necessary to reproduce the problem.

Appart from that, don't use render="@all". It's generally considered a bad practice to render the whole page again using ajax. To do that, just perform an standard POST request. In your case, you can render only the other form, or even better, the component you're particularly interested in.

Here you've a tested SSCCE about your issue, which works ;-)

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core">
<h:head>
    <title>Test page</title>
</h:head>
<h:body>
    <h:form id="form1">
        <h:selectOneListbox size="1" value="#{adminController.model}">
            <f:ajax event="valueChange" render=":form2" />
            <f:selectItems value="#{adminController.selectItem}" var="p"
                itemValue="${p.name}" itemLabel="${p.name}" />
        </h:selectOneListbox>

    </h:form>
    <h:form id="form2">
        <h:selectOneListbox size="1" value="#{adminController.model}">
            <f:ajax event="valueChange" render=":form1" />
            <f:selectItems value="#{adminController.selectItem}" var="p"
                itemValue="${p.name}" itemLabel="${p.name}" />
        </h:selectOneListbox>
        <h:commandButton value="Print">
            <f:ajax event="click" listener="#{adminController.printAjax}" />
        </h:commandButton>

    </h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class AdminController implements Serializable {

    public AdminController() {
        System.out.println("Bean created");
    }

    public class Product {

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        String name;

        public Product(String name) {
            this.name = name;
        }

    }

    String model;

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public List<Product> getSelectItem() {
        return Arrays.asList(new Product("Prod1"), new Product("prod2"));
    }

    public void printAjax() {
        System.out.println("Printing " + model);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top