AutoComplete do PrimeFaces não retorna valor algum

7 respostas
J

Na verdade, nem sei se o autoComplete chega a ser consultado.

A chamada do p:autoComplete:

<p:autoComplete value="#{autoCompleteEndereco.enderecoSelecionado}" id="enderecoInput" 
completeMethod="#{autoCompleteEndereco.completaEndereco}" var="e" itemLabel="#{e.id}" itemValue="#{e.logradouro}" converter="#{enderecoConverter}" />

A Classe cujo método invoca o DAO com a lista de sugestõesr:

public class AutoCompleteEndereco {
   private EnderecoBean enderecoSelecionado;
   // Construtor, getters e setters omitidos...      
   public List<EnderecoBean> completaEndereco(String query) {
		
      List<EnderecoBean> sugestoes = new ArrayList<EnderecoBean>();
      EnderecoDAO dao = null;
      try {
         sugestoes = dao.getEnderecos();
      }
      // Catch omitido...
      for(EnderecoBean eb : sugestoes) {
         if(eb.getLogradouro().startsWith(query)) {
	    sugestoes.add(eb);
         }
      }
      return sugestoes;
      // Etc...

faces-config.xml:

<converter>
        <converter-id>autoCompleteEndereco</converter-id>
        <converter-for-class>beans.AutoCompleteEndereco</converter-for-class>
    </converter>

Os métodos da Classe que implementa o Converter:

@Override
    public Object getAsObject(FacesContext fc, UIComponent uic, String submittedValue) {
       iif(submittedValue.trim().equals("")) {
          return null;    
       }
       else {
          return (Object)submittedValue;
       }
    }
@Override
    public String getAsString(FacesContext fc, UIComponent uic, Object value) {
    if(value == null || value.equals("")) {
          return "";
       } 
       else {
          return String.valueOf(value);
       }
        
    }

Essa parte da conversão ficou confusa para mim.
O que ele precisa converter? O que o usuário digitou (uma String) ou o Objeto que estou tentando mandar como sugestão no SELECT? (Que é um List de objetos do tipo EnderecoBean).

7 Respostas

aechiara

qual versão do Primefaces você está usando ?

você está tentando usar o exemplo do Pojo, certo ?
note que no seu código está considerando case, então se o endereço é “Rua A”, e você digitar “rua a” ele não vai encontrar

rode em mode debug, e veja se ele está chegando até o “completaEndereco”

no exemplo do site do primefaces, eles testam no converter para ver se foi digitado um número, acho que no seu caso, se não tiver número, não vai precisar do converter

J

Sim, estou tentando adaptar o exemplo do POJO.
Meu POJO é esse:

public class EnderecoBean {
    
   private Integer id;
   private String tipo;
   private String logradouro;
   private String cep;
   private Integer bairro_id;
           
   public EnderecoBean() {
   }
   
   public EnderecoBean(Integer id, String tipo, String logradouro, String cep, Integer bairro_id) {
   
      this.id = id;
      this.tipo = tipo;
      this.logradouro = logradouro;
      this.cep = cep;
      this.bairro_id = bairro_id;
          
   }
   // getters e setters omitidos.
}

PrimeFaces 2.2.1 (Versão que vem no NetBeans 7.1)

J

O que eu espero que ele retorne de sugestão, é o atributo logradouro.

O método do EnderecoDAO:

public List getEnderecos() throws Exception {
       
      PreparedStatement ps = null;
      Connection connection;
      ResultSet rs = null;
      
      try {
         connection = this.conn; 
         ps = connection.prepareStatement("SELECT * FROM enderecos");
         rs = ps.executeQuery();
         List<EnderecoBean> lista = new ArrayList<EnderecoBean>();
         while(rs.next()) {
            Integer id = rs.getInt("id");
            String tipo = rs.getString("tipo");
            String logradouro = rs.getString("logradouro");
            String cep = rs.getString("cep");
            Integer bairro_id = rs.getInt("bairro_id");
            lista.add(new EnderecoBean(id, tipo, logradouro, cep, bairro_id));
         }
         return lista;
      }
      catch(SQLException sqle) {
         throw new Exception(sqle);    
      }
      finally {
         ConnectionFactory.closeConnection(conn, ps, rs);
      }
       
   }
aechiara
javadalberto:
O que eu espero que ele retorne de sugestão, é o atributo logradouro.

O método do EnderecoDAO:

public List getEnderecos() throws Exception {
       
      PreparedStatement ps = null;
      Connection connection;
      ResultSet rs = null;
      
      try {
         connection = this.conn; 
         ps = connection.prepareStatement("SELECT * FROM enderecos");
         rs = ps.executeQuery();
         List<EnderecoBean> lista = new ArrayList<EnderecoBean>();
         while(rs.next()) {
            Integer id = rs.getInt("id");
            String tipo = rs.getString("tipo");
            String logradouro = rs.getString("logradouro");
            String cep = rs.getString("cep");
            Integer bairro_id = rs.getInt("bairro_id");
            lista.add(new EnderecoBean(id, tipo, logradouro, cep, bairro_id));
         }
         return lista;
      }
      catch(SQLException sqle) {
         throw new Exception(sqle);    
      }
      finally {
         ConnectionFactory.closeConnection(conn, ps, rs);
      }
       
   }

tenta o exemplo do Simple então, pega dessa URL: [url]http://www.primefaces.org/showcase-labs/ui/autoCompleteBasic.jsf[/url]

só para te poupar o trabalho, vou colar aqui:

public List<String> completaEndereco(String query) {  
        List<String> results = new ArrayList<String>();  
          
       // busca no seu DAO usando query como parametro
      // e itera nos endereços aqui

      for (EnderecoBean end: enderecos) {  
            results.add(end.getLogradouro);  
        }  
          
        return results;  
    }
e no xhtml:
<p:autoComplete value="#{autoCompleteEndereco.enderecoSelecionado}" id="enderecoInput"   
    completeMethod="#{autoCompleteEndereco.completaEndereco}"  />

algo assim, faça os ajustes necessários para a sua estrutura aí, mas a idéia básica é essa

J

A questão é, porque tenho que usar de novo o DAO se já foi feito isso antes?

E o que são na verdade esses argumentos Object e String que precisam ser convertidos?

aechiara

javadalberto:
A questão é, porque tenho que usar de novo o DAO se já foi feito isso antes?

E o que são na verdade esses argumentos Object e String que precisam ser convertidos?

não precisa, se você já tiver os dados, pode adicioná-los a lista e devolver para a página, aí a decisão é sua, se é necessário ou não ir até o banco toda vez

quanto ao Converter, é um recurso do JSF para quando você não utiliza um tipo que possuí conversão automática. Exemplo, você tem um campo para valores monetários, para nós aqui no Brasil o separador de centavos é vírgula, mas o padrão (BigDecimal, Float, Double) é o ponto, então é necessário um conveter para pegar 10,00 (que foi digitado na página e é uma String) e conveter para 10.00 (número) na hora de passar para o ManagedBean, mas quando for exibir na página, você vai querer que mostre 10,00 e não 10.00 como está no seu Bean, aí o Converter faz a conversão de 10.00 (número) para 10,00 (String) para exibir na página .

public Object getAsObject

recebe da página e converte para um tipo do java

public String getAsString

recebe do bean, e conveter para String para mostrar na página

mas no seu caso, não precisa disso, pois você está trabalhando com Strings, é só tirar o conveter da tag do autocomplete

Deu para entender ? Sugiro uma lida rápida em Converters e Validators do JSF

J

Obrigado pela paciência.

Vou revisar e fazer os testes, qualquer novidade (boa ou ruim) eu aviso.

Valeu pela força!

Criado 1 de março de 2012
Ultima resposta 2 de mar. de 2012
Respostas 7
Participantes 2