Richfaces e Dropdown aninhados em três niveis

1 resposta
lusilva1982

Pessoal, eu também consegui fazer funcionar com dois dropdowns dependentes, mas e quando for preciso trabalhar com mais niveis?

Quero montar a seguinte situação Pais, Estado e Cidade.
Até o Pais e Estado, tudo bem, funciona. Mas quando eu seleciono o Estado o valor do dropdown não é setado no ManagerBean. Criei um Converter seguindo o exemplo do Rafael Ponte, mesmo assim não funcionou, vejam:

<h:form>  
     <h:panelGrid id="panel" rendered="true" border="0" columns="2" width="500" cellpadding="1" cellspacing="2">  
   
         <h:outputLabel value="Pais" for="pais"/>  
         <h:selectOneMenu id="pais"  
                          value="#{umb.pessoa.pais.id_pais}"  
                          rendered="true">  
             <f:selectItems value="#{umb.paises}"/>  
             <a4j:support event="onchange"   
                          ajaxSingle="true"  
                          action="#{umb.actionCarregarEstados}"  
                          reRender="estado"/>  
         </h:selectOneMenu>  
   
         <h:outputLabel value="Estado" for="estado"/>        
         <h:selectOneMenu id="estado"  
                          value="#{umb.pessoa.estado.id_estado}"  
                          rendered="true">  
             <f:selectItems value="#{umb.estados}"/>  
             <f:converter converterId="estadoConvert"/>  
             <a4j:support event="onchange"  
                          ajaxSingle="true"  
                          action="#{umb.actionCarregarCidades}"  
                          reRender="cidade"/>  
         </h:selectOneMenu>  
   
         <h:outputLabel value="Cidade" for="cidade"/>  
         <h:selectOneMenu id="cidade"  
                          value="#{umb.pessoa.cidade.id_cidade}"  
                          rendered="true">  
             <f:selectItems value="#{umb.cidades}"/>  
         </h:selectOneMenu>  
   
     </h:panelGrid>  
 </h:form>

O manager Bean:

public class UirapuruManagerBean {  
     private RegiaoDAO regiaoDao = null;  
     private Pessoa pessoa = new Pessoa();     
     private SelectItem[] estados;  
     private SelectItem[] cidades;  
   
     public UirapuruManagerBean(){  
         this.regiaoDao = new RegiaoDAO();  
   
         this.estados   = new SelectItem[1];  
         estados[0]     = new SelectItem("0","Escolha seu Estado");  
   
         this.cidades   = new SelectItem[1];  
         cidades[0]     = new SelectItem("0","Escolha sua Cidade");  
     }  
   
     /** 
      * Obtem todos os registros de paises e transformá-os em um 
      *  array de itens do tipo interpretado pelo JSF.   
      * @return Array de SelectItem do Faces 
      */  
     public SelectItem[] getPaises(){  
         List<Pais> lp = regiaoDao.getAllPais();  
         List<SelectItem> itens = new ArrayList<SelectItem>(lp.size());  
   
         for( Pais p : lp ){  
             itens.add( new SelectItem(p.getId_pais(), p.getNm_pais()) );  
         }// for end  
         return itens.toArray( new SelectItem[itens.size()] );  
     }  
   
     /** 
      * Obtem todos os registros de estados relacionados ao páis informado e 
      *  transformá-os em um array de itens do tipo interpretado pelo JSF.  
      * @param Identificação do Pais 
      * @return Array de SelectItem do Faces 
      */  
     public SelectItem[] getEstadosByPais(int id_pais){  
         List<Estado> estados   = regiaoDao.getEstadosDoPais(id_pais);  
         List<SelectItem> itens = new ArrayList<SelectItem>(estados.size());  
   
         for( Estado e : estados ){  
             itens.add( new SelectItem(e.getId_estado(), e.getNm_estado()) );  
         }// for end  
         return itens.toArray( new SelectItem[itens.size()] );  
     }  
   
     /** 
      *  
      * @param Identificação do Estado 
      * @return Array de SelectItem com as Cidades 
      */  
     public SelectItem[] getCidadesByEstado(int id_estado){  
         System.out.println("ID-Estado: " + id_estado);  
         List<Cidade> cidades   = regiaoDao.getCidadesDoEstado(id_estado);  
         List<SelectItem> itens = new ArrayList<SelectItem>(cidades.size());  
   
         for( Cidade c : cidades ){  
             itens.add( new SelectItem(c.getId_cidade(), c.getNm_cidade()) );  
         }// for end  
         return itens.toArray( new SelectItem[itens.size()] );  
     }  
   
     /** 
      *  
      * @return 
      */  
     public String actionCarregarEstados(){  
         this.estados = getEstadosByPais( getPessoa().getPais().getId_pais() );  
         return "SUCCESS";  
     }  
   
     /** 
      *  
      * @return 
      */  
     public String actionCarregarCidades(){  
         this.cidades = getCidadesByEstado( getPessoa().getEstado().getId_estado() );  
         return "SUCCESS";  
     }  
   
     public SelectItem[] getEstados() {  
         return estados;  
     }  
   
     public void setEstados(SelectItem[] estados) {    
         this.estados = estados;  
     }  
   
     public Pessoa getPessoa() {  
         return pessoa;  
     }  
   
     public void setPessoa(Pessoa pessoa) {  
         this.pessoa = pessoa;  
     }  
   
     public SelectItem[] getCidades() {  
         return cidades;  
     }  
   
     public void setCidades(SelectItem[] cidades) {  
         this.cidades = cidades;  
     }  
   
 }

Vou colocar o converter aqui, por que acredito que o problema seja nele! Eu fiz seguindo a dica do Rafael Ponte - http://www.rponte.com.br/2008/07/26/entity-converters-pra-da-e-vender/

public class EstadoConvert implements Converter{  
   
     /*  
      * @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String) 
      */  
     public Object getAsObject( FacesContext arg0, UIComponent component, String valor ){  
         SelectItem selectedItem = this.getSelectedItemByIndex(component, Integer.parseInt(valor));  
         if( selectedItem != null )  
             return selectedItem.getValue();  
           
         return null;  
     }  
   
   
     protected SelectItem getSelectedItemByIndex( UIComponent component, int index ){  
   
         List<SelectItem> items = this.getSelectItems(component);  
         int size = items.size();  
   
         if( index > -1 && size > index ){  
             return items.get(index);  
         }  
   
         return null;  
     }  
       
     protected List<SelectItem> getSelectItems( UIComponent component ){  
   
         List<SelectItem> items = new ArrayList<SelectItem>();  
   
         int childCount = component.getChildCount();  
         if( childCount == 0 )  
             return items;  
   
         List<UIComponent> children = component.getChildren();  
         for( UIComponent child : children ){  
             if( child instanceof UISelectItem ){  
                 this.addSelectItem((UISelectItem) child, items);  
             }else if( child instanceof UISelectItems ){  
                 this.addSelectItems((UISelectItems) child, items);  
             }  
         }  
   
         return items;  
     }  
   
   
     protected void addSelectItem( UISelectItem uiItem, List<SelectItem> items ){  
   
         boolean isRendered = uiItem.isRendered();  
         if( !isRendered ){  
             items.add(null);  
             return;  
         }  
   
         Object value = uiItem.getValue();  
         SelectItem item;  
   
         if( value instanceof SelectItem ){  
             item = (SelectItem) value;  
         }else{  
             Object itemValue = uiItem.getItemValue();  
             String itemLabel = uiItem.getItemLabel();  
             // JSF throws a null pointer exception for null values and labels,  
             // which is a serious problem at design-time.  
             item = new SelectItem(itemValue == null ? "" : itemValue,  
                     itemLabel == null ? "" : itemLabel, uiItem.getItemDescription(), uiItem.isItemDisabled());  
         }  
   
         items.add(item);  
     }  
   
   
     @SuppressWarnings("unchecked")  
     protected void addSelectItems( UISelectItems uiItems, List<SelectItem> items ){  
   
         boolean isRendered = uiItems.isRendered();  
         if( !isRendered ){  
             items.add(null);  
             return;  
         }  
   
         Object value = uiItems.getValue();  
         if( value instanceof SelectItem ){  
             items.add((SelectItem) value);  
         }else if( value instanceof Object[] ){  
             Object[] array = (Object[]) value;  
             for( int i = 0; i < array.length; i++ ){  
                 // TODO test - this section is untested  
                 if( array[i] instanceof SelectItemGroup ){  
                     resolveAndAddItems((SelectItemGroup) array[i], items);  
                 }else{  
                     items.add((SelectItem) array[i]);  
                 }  
             }  
         }else if( value instanceof Collection ){  
             Iterator<SelectItem> iter = ((Collection<SelectItem>) value).iterator();  
             SelectItem item;  
             while( iter.hasNext() ){  
                 item = iter.next();  
                 if( item instanceof SelectItemGroup ){  
                     resolveAndAddItems((SelectItemGroup) item, items);  
                 }else{  
                     items.add(item);  
                 }  
             }  
         }else if( value instanceof Map ){  
             for( Map.Entry<Object, Object> entry : ((Map<Object, Object>) value).entrySet() ){  
                 Object label = entry.getKey();  
                 SelectItem item = new SelectItem(entry.getValue(),  
                         label == null ? (String) null : label.toString());  
                 // TODO test - this section is untested  
                 if( item instanceof SelectItemGroup ){  
                     resolveAndAddItems((SelectItemGroup) item, items);  
                 }else{  
                     items.add(item);  
                 }  
             }  
         }  
     }  
   
     protected void resolveAndAddItems( SelectItemGroup group, List<SelectItem> items ){  
         for( SelectItem item : group.getSelectItems() ){  
             if( item instanceof SelectItemGroup ){  
                 resolveAndAddItems((SelectItemGroup) item, items);  
             }else{  
                 items.add(item);  
             }  
         }  
     }  
     /*  
      * @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object) 
      */  
     public String getAsString( FacesContext arg0, UIComponent arg1, Object obj ){  
         String key = "0";  
   
         if( obj instanceof Integer ){  
             key = String.valueOf( obj );  
         }  
           
         return key;  
     }  
   
 }

Alguém pode me ajudar, por favor?
Alguma dica pelo menos?

Valeu!

1 Resposta

lusilva1982

Eu resolvi o problema colocando o escopo como session ou application:

<managed-bean>
		<managed-bean-name>umb</managed-bean-name>
		<managed-bean-class>uirapuru.control.mb.UirapuruManagerBean</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
	</managed-bean>

Não é a melhor maneira, inclusive acredito que não seja a correta, porém, fazendo este tipo de persistência é possível manter o valor selecionado no dropdown Estado, para assim carregar as cidades.

Falow!

Criado 15 de julho de 2009
Ultima resposta 20 de jul. de 2009
Respostas 1
Participantes 1