Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with Primefaces 3.0.M2 SelectOneMenu Ajax behavior

Tags:

I am having trouble with implementing two SelectOneMenu controls, where data in the second one depends on the selection made in the first. This example on the primeFaces showcase is almost the same as what I want to implement: http://www.primefaces.org/showcase-labs/ui/pprSelect.jsf

except that I have to get the data from a database.

The above example is working correctly in the same project. I am using NetBeans 7.0 with GlassFish 3.1 and PrimeFaces 3.0.M2, the latest drop (20th June 2011).

The source code of the JSF page and the managed bean is attached.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.prime.com.tr/ui" 
  xmlns:f="http://java.sun.com/jsf/core">
<h:head><title>Facelet Title</title></h:head>
<h:body>
 <p:log />
    <center>
        <h:form>
            <h:outputText value="State: "/>
            <p:selectOneMenu id="selectState" value="#{stateCityBean.selectedStateArray}">
                <f:selectItem itemLabel="Select Any" itemValue="Empty String"/>
                <p:ajax update="selectCity" listener="#{stateCityBean.updateCityMap}"/>
                <f:selectItems value="#{stateCityBean.stateMap}" />
            </p:selectOneMenu>
            <p></p>
            <h:outputText value="City: "/>
            <p:selectOneMenu id="selectCity" value="#{stateCityBean.selectedCityArray}">
                <f:selectItem itemLabel="Select Any" itemValue="Empty String"/>
                <f:selectItems value="#{stateCityBean.cityMap}"/>
            </p:selectOneMenu>
        </h:form>
    </center>
</h:body>

StateCityBean.java

package com.xyz.mbeans;
import com.iwizability.priceinfo.dao.*;
import com.iwizability.priceinfo.pojo.*;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.event.ValueChangeEvent;

@ManagedBean
@SessionScoped
public class StateCityBean {
private String selectedStateArray;
private Map<String, State> StateMap;
private Map<String, City> CityMap;
private String selectedCityArray;

public StateCityBean() {
    System.out.println("Inside.............. ");
    StateMap = new LinkedHashMap<String, State>();
    CityMap = new LinkedHashMap<String, City>();
}

public String getSelectedStateArray() {return selectedStateArray;}

public void setSelectedStateArray(String selectedStateArray) {this.selectedStateArray = selectedStateArray;}

public Map<String, State> getStateMap() {
    StateDaoImpl stateObj = new StateDaoImpl();
    StateMap = stateObj.getState();
    return StateMap;
}

public void setStateMap(Map<String, State> stateArray) {this.StateMap = stateArray;}

public String getSelectedCityArray() {return selectedCityArray;}

public void setSelectedCityArray(String selectedCityArray) {this.selectedCityArray = selectedCityArray;}

public Map<String, City> getCityMap() {
    CityDaoImpl cityObj = new CityDaoImpl();
    int stateId = 0;
    if (selectedStateArray != null && !selectedStateArray.equals("")) {
        stateId = StateMap.get(selectedStateArray).getId();
    }
    CityMap = cityObj.getCity(stateId);
    return CityMap;
}

public void setCityMap(Map<String, City> CityArray) {
    this.CityMap = CityArray;
}

public void updateCityMap() {
    CityDaoImpl cityObj = new CityDaoImpl();
    int stateId = 0;
    if (selectedStateArray != null && !selectedStateArray.equals("")) {
        stateId = StateMap.get(selectedStateArray).getId();
        this.CityMap = cityObj.getCity(stateId);
    }
 }

}

On debugging, I can see that the updateCityMap method is invoked but the SelectedStateArray variable is null. Even force changing the value of bound CityMap variable does not update the selectCity drop down.

As you would have guessed, I am new to JSF, but the problem is compounded by the fact that I am using a still in development version of the tag library...

like image 429
agileai Avatar asked Jun 22 '11 05:06

agileai


2 Answers

I created a demo for the exact same situation you describe in your project. I have a state and city <p:selectOneMenu/> elements on my page. You select a state, and the cities update. If a different state is selected, the city is erased since it may not exist in the state.

The difference is that I use <p:ajax event="change" update="cities, cs"/> to update the elements, and an actionListener to update the city if the state is different.

<p:selectOneMenu id="states" value="#{dataBean.selectedState}"
   valueChangeListener="#{dataBean.stateChangeListener(event)}"
   style="width: 150px;">
   <f:selectItem itemLabel="" itemValue=""/>
   <f:selectItems value="#{dataBean.states}"/>
   <p:ajax event="change" update="cities, cs"/>
</p:selectOneMenu>
<h:outputLabel value="City:" for="cities"/>
<p:selectOneMenu id="cities" 
   value="#{dataBean.selectedCity}" 
   style="width: 150px;">
   <f:selectItem itemLabel="" itemValue=""/>
   <f:selectItems value="#{dataBean.cities}"/>
   <p:ajax event="change" update="cs" />
 </p:selectOneMenu>

The whole project and demo code can be found on my blog. I saw this post and decided to post my project. [blog]: http://javaevangelist.blogspot.com/2012/07/primefaces-ajax-enabled.html

like image 91
John Yeary Avatar answered Nov 06 '22 05:11

John Yeary


Primefaces is trying something diffent. I dont know why. First of all you must know these releases are not stable. When you analys code with firebug you will shove this. Lets assume two combo who has ids countries and cities when you changed the first combo cities update correcty but cities combo' id change to cities_input they add _input prefix. When I analys primefaces source code. Thereare codes something like traverse tree if visited change id by adding _input or _panel. So if you change the combo in second time. Everything work perfect except you said update cities but there is no component who has id cities becouse it has new id cities_input. So your ajax does not work correctly. But they correct this bug in 3.0m4 or after releases.

This is the problem. Another example of this problem it is bug someone open jira for this. İf you are using login with spring security j_username, j_password change to j_username_input j_password_input. So this breaks the standart and code does not work in second ajax requests. Hope this helps..

pay attention to lionhearts words. Primefaces namespaces changed in 3.m4 in pages use this. xmlns:p="http://primefaces.org/ui"

like image 29
Mustafa SAHIN AYDIN Avatar answered Nov 06 '22 07:11

Mustafa SAHIN AYDIN