2011-06-22 54 views
21

Tengo problemas para implementar dos controles SelectOneMenu, donde los datos en el segundo dependen de la selección realizada en el primero. Este ejemplo en el escaparate de PrimeFaces es casi lo mismo que lo que deseo implementar: http://www.primefaces.org/showcase-labs/ui/pprSelect.jsfProblema con Primefaces 3.0.M2 SelectOneMenu Comportamiento Ajax

excepto que tengo que obtener los datos de una base de datos.

El ejemplo anterior funciona correctamente en el mismo proyecto. Estoy usando NetBeans 7.0 con GlassFish 3.1 y PrimeFaces 3.0.M2, la última versión (20 de junio de 2011).

Se adjunta el código fuente de la página JSF y el bean administrado.

<?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); 
    } 
} 

}

En la depuración, puedo ver que se invoca el método updateCityMap pero la variable SelectedStateArray es nulo. Incluso forzar el cambio del valor de la variable CityMap encuadernada no actualiza el menú desplegable selectCity.

Como es de suponer, Soy nuevo en JSF, pero el problema se ve agravado por el hecho de que estoy usando una versión todavía en desarrollo de la biblioteca de etiquetas ...

+0

Esto sólo puede ser parte de su problema, pero su atributo de actualización se refería directamente a su ciudad desplegable componente por id 'update =" selectCity "'. El problema con esto es que en JSF el '' antepondrá su id a los elementos secundarios de forma predeterminada. Intente especificar el siguiente atributo en su '' y vea si eso soluciona su problema, 'prependId =" false "' –

+1

@maple_shaft: Esta es la forma en que se usa el atributo de actualización en todos los ejemplos que he visto ... Probé deshabilitar prependId pero no parece resolver el problema. – agileai

+0

Entonces, agregué un atributo event = "valueChange" a p: ajax y ahora recibo un error: j_idt8: selectState: Validation Error: El valor no es válido Al buscar el error de validación, parece que la web está llena de esto problema. Con JSF en general y también con PrimeFaces específicamente: http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=6947 http://www.java.net/blogs/lamine_ba http : //www.coderanch.com/t/501774/JSF/java/JSF-PrimeFace-Validation-Error-Value Traté de cambiar el alcance a viewscoped, sin embargo, eso tampoco me está haciendo bien ... – agileai

Respuesta

0

hice un estado -> seleccionar ciudad en mi proyecto jsf de la misma manera que lo hizo. Las únicas diferencias que he encontrado son:

  • mi p:ajax tiene un evento change: <p:ajax event="change" update="city" listener="#{contatoMB.filterCities}" />.
  • mi p:ajax viene pasado después del f:selectItems pero este no debería ser el problema.
  • mi lista de f:selectItems en la ciudad seleccione es List<javax.faces.model.SelectItem> y no Map<String, City>, ¿ha intentado utilizar SelectItem s en lugar de su mapa?
  • mi formulario tiene una identificación y prependId falso <h:form id="contact-form" prependId="false">, una vez más, este no debería ser el problema.
  • mi h:selectOneMenu está dentro de un p:panel, algunos componentes de PrimeFaces se comportan de una manera extraña cuando están dentro o fuera de otros componentes.

Si nada de esto funciona, tal vez el problema sea la versión de PrimeFaces que está utilizando. Mi versión PrimeFaces es 2.2.1.

0

utilizo PrimeFaces 3.0.M4 con espacios de nombres:

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:p="http://primefaces.org/ui"> 

Parece que funciona bien.

1

Primefaces está intentando algo diferente. No sé por qué. Antes que nada debes saber que estas versiones no son estables. Cuando analys codifique con firebug lo empujará. Supongamos dos combo que tiene ids países y ciudades cuando cambiaste la primera actualización de las ciudades combinadas correctamente, pero las ciudades combo 'id cambian a cities_input agregan _input prefix. Cuando analizo el código fuente de Primefaces.Hay códigos como el árbol transversal si se visitan cambian la identificación agregando _input o _panel. Entonces, si cambias el combo por segunda vez. Todo funciona perfecto, excepto que dices ciudades de actualización, pero no hay ningún componente que tenga ciudades de identificación, ya que tiene una nueva id de ciudades_input. Entonces tu ajax no funciona correctamente. Pero corrigen este error en 3.0m4 o después de las versiones.

Este es el problema. Otro ejemplo de este problema es si alguien abre jira por esto. Si está utilizando el inicio de sesión con seguridad de primavera j_username, j_password cambie a j_username_input j_password_input. Esto rompe el estándar y el código no funciona en las segundas solicitudes de Ajax. Espero que esto ayude ..

preste atención a las palabras de lionhearts. Los espacios de nombres de Primefaces cambiados en 3.m4 en las páginas usan esto. xmlns: p = "http://primefaces.org/ui"

0

Tal vez sea la versión PrimeFaces pero su método de actualización en su frijol se ve bastante complicado.

¿Por qué no recuperar el Objeto de la selección del evento ajax ?, de esta manera no necesita definir esa variable.

public void update(AjaxBehaviorEvent event) 
{ 
    Object selectOneMenuObject = ((UIOutput)event.getSource()).getValue(); 

    //String selectedStateArray = (String)((UIOutput)event... 
    //update temporary collection of second SelectOneMenu 
} 

No sé si eso te ayudará, pero así es como lo hago.

2

Creé una demostración para la misma situación que usted describe en su proyecto. Tengo un estado y ciudad <p:selectOneMenu/> elementos en mi página. Selecciona un estado y las ciudades se actualizan. Si se selecciona un estado diferente, la ciudad se borrará ya que puede no existir en el estado.

La diferencia es que uso <p:ajax event="change" update="cities, cs"/> para actualizar los elementos, y un actionListener para actualizar la ciudad si el estado es diferente.

<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> 

Todo el proyecto y el código de demostración se pueden encontrar en mi blog. Vi esta publicación y decidí publicar mi proyecto. [Blog]: http://javaevangelist.blogspot.com/2012/07/primefaces-ajax-enabled.html

0

sólo debe añadir

event="change" 

a p: ajax

Cuestiones relacionadas