Problema em popular <rich:comboBox> - [resolvido]

olá pessoal,

Muito provavelmente o problema é conceitual, mas não consigo enxergá-lo. Eu não consigo popular um rich:comboBox com os valores de uma lista.

a definição do combobox é:

<rich:comboBox width="350" listHeight="50px"> <f:selectItems value="#{anamanRegisterServiceMB.entities}" /> </rich:comboBox>

o managed bean está mapeado no faces-config.xml da seguinte maneira:

<managed-bean> <managed-bean-name>anamanRegisterServiceMB</managed-bean-name> <managed-bean-class>anaman.mb.AnamanRegisterMB</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

e ele é assim:

(...)
private ArrayList<SelectItem> entities;
(...)

public ArrayList<SelectItem> getEntities() {
       List<SelectItem> entityList = new LinkedList<SelectItem>();
       List ent = ars.getRegisterEntityList();
       AnamanRegister entity = new AnamanRegister();
       for (int i = 0; i < ent.size(); i++) {
           entityList.add(new SelectItem(ent.get(i), entity.getRegisterEntity()));
       }
       return entities;
   }
(...)

o método que define a lista getRegisterEntityList() é:

private List registerEntityList;
(...)
public List getRegisterEntityList() {
       registerEntityList = null;
       try {
           registerEntityList = arD.getRegisterEntityList();
       } catch (AnamanException e) {
           System.out.println("[AnamanRegisterService] - error retrieving registerEntityList");
           e.printStackTrace();
           return null;
       }
       return registerEntityList;
   }
(...)

e o método no DAO que monta a lista de entidades é:

public List getRegisterEntityList() throws AnamanException { String sql = "SELECT DISTINCT registerEntity FROM anaman_register"; return this.getManyByCriteria(sql, 1); }

Agradeço desde já!
Gustavo

Gustavo, qual erro ocorre ?
Ou simplesmente ele não preenche a o comboBox ?

realmente faltou eu colocar isso…

javax.servlet.ServletException: Value of tag <selectItems> attribute is incorrect. javax.faces.webapp.FacesServlet.service(FacesServlet.java:277) org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178) org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290) org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368) org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)

A propósito, troquei a tag

<f:selectItems value="#{anamanRegisterServiceMB.entities}" />

por

<f:selectItem value="#{anamanRegisterServiceMB.entities}" />

E renderizou a tela (antes não fazia), mas o combo não é populado…

Cara eu ainda não trabalhei com o rich combobox, mas pela referência do manual vc deve usar ele assim:

<rich:comboBox value="#{bean.state}" suggestionValues="#{bean.suggestions}" />

Então em “suggestionValues” você não deveria definir a propriedade do seu bean que retorna a lista ?

alexegidio a PROPRIEDADE Sugestion é apenas para mostrar sugestões.Ou seja. Quando a pessoa estiver digitando PED, e estiver no beam a palavra PEDRA,
automaticamente sera mostrada a palavra PEDRA para o usuario.É como fosse o search do google…

Pelo que estou vendo aqui.O problema n está no jsp e sim na hora de chamar os valores pelo bean.

Faz assim amigo.Cria uma lista manualmente e adicione valores nela.E ae chame esta lista na sua pagina .JSP . SE funcionar e vai funcionar o problema é que o seu bean nao esta armazenando nada na lista e ae quando voce chama os dados usando a pagina jsp, nada é trazido.Aonde está o erro.Ae precisa ver o codigo de fonte e as classes para analisar


public class ListasBean {

   public List<SelectItem> getTeste() {
          List<SelectItem> listaTeste = new ArrayList<SelectItem>();
          listaTeste .add(new SelectItem("1"));
          listaTeste .add(new SelectItem("2"));
          listaTeste .add(new SelectItem("3"));
          listaTeste .add(new SelectItem("4"));
          listaTeste .add(new SelectItem("5"));
          listaTeste .add(new SelectItem("6"));
          listaTeste .add(new SelectItem("7"));
          listaTeste .add(new SelectItem("8"));
          return listaTeste;
}

andreihirata,

funcionou! realmente o problema está no bean mesmo. estou debugando agora! obrigado pela ajuda!

[edit] na verdade penso que o problema esteja na conversão para a lista de selectItems, faz sentido?

Gustavo

Vou dar uma olhada na conversao…Um momento
Copila ae e mostra a linha q ta dando erro,assim facilita para mim

Voce precisa me mostrar as classes relacionadas.As classes entidades,dao para que possa analisar.
Nao vi o motivo do uso da funcao de converter.Geralmente eu uso a lista data model para armazenar os dados da minha consulta, depois pego estes dados e coloco em uma lista

Um pequeno trecho explicativo.RITOS é uma tabela minha

@Stateless
public class RitosFacade implements RitosFacadeLocal {
    @PersistenceContext
    private EntityManager em;

    public List<Ritos> findAll() {
        return em.createQuery("select object(o) from Ritos o").getResultList();
    }
 public DataModel getTodos()
            throws Exception {

        model =
                new ListDataModel(facade.findAll());
        return model;

    }

<rich:comboBox defaultLabel="#{bundle['anamanRegisterServiceJSP.selectEntity']}" width="300" listHeight="100px"> <f:selectItems value="#{anamanRegisterServiceMB.entities}" /> </rich:comboBox>

A exception é:

javax.servlet.ServletException: /jsf/AnamanRegisterService.jsp(24,11) '#{anamanRegisterServiceMB.entities}' Error reading 'entities' on type anaman.mb.AnamanRegisterMB
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:277)
	org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
	org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
	org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
	org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)

e a root cause é:

org.apache.jasper.el.JspELException: /jsf/AnamanRegisterService.jsp(24,11) '#{anamanRegisterServiceMB.entities}' Error reading 'entities' on type anaman.mb.AnamanRegisterMB
	org.apache.jasper.el.JspValueExpression.getValue(JspValueExpression.java:107)
	javax.faces.component.UISelectItems.getValue(UISelectItems.java:141)
	org.ajax4jsf.util.SelectUtils.getSelectItems(SelectUtils.java:84)
        (...)

Talvez se eu explicar um pouco como estão as coisas aqui ajude um pouco.

Tenho um pacote model onde ficam os POJOs. Todos tem um construtor padrão({ }) e um construtor com todos os campos da tabela, getters e setters, são serializados e implementam equals(), hashCode() e toString(). Um dos POJOs é o AnamanRegister e outro deles é o AnamanRegisterEntityDTO, que extende AnamanRegister, mas só tem um campo de String chamado entity. Criei esse POJO para armazenar uma consulta na tabela anaman_register para que eu pudesse fazer filtros sequenciais. Então eu teria um primeiro filtro por entidade e diminuir o escopo da busca até ter poucas opções para o usuário.

Um outro pacote é o jdbc que como o nome sugere faz a interação com o banco, uma das classes é o AnamanRegisterDAO que centraliza os PreparedStatement. Para eu conseguir fazer uma consulta DISTINCT na coluna registerEntity do banco passo a string sql e um int para um método getManyByCriteria(String sql, int constructorType). O constructorType cai em um switch-case onde aponto o AnamanRegisterEntityDTO. E então consigo retornar uma lista de Strings apenas com os valores de registerEntity.

Depois tenho um pacote core.input onde centralizo as regras de negócio para entrada de dados. Aqui tenho uma classe chamada AnamanRegisterService que centraliza as regras de negócio para essa parte do sistema. Uma das listas que implementei aqui é a registerEntityList().

E, finalmente, no pacote mb ficam os managed beans. Um deles é o AnamanRegisterMB que pensei em usar como ponte entre as telas do sistema e as regras de negócio. Esse bean é o seguinte:

[code]package anaman.mb;

import java.util.List;
import java.util.ArrayList;

import javax.faces.model.SelectItem;

import anaman.core.input.AnamanRegisterService;
import anaman.model.AnamanRegister;

public class AnamanRegisterMB {
// Init
// ---------------------------------------------------------------------------------------
private AnamanRegisterService ars = AnamanRegisterService.getInstance();
private List entities;
//private AnamanRegisterService selectedItem;

private List entityList = ars.getRegisterEntityList();

/*public ArrayList<SelectItem> getEntities() {
	//List<SelectItem> entityList = new LinkedList<SelectItem>();
	List ent = ars.getRegisterEntityList();
	//AnamanRegister entity = new AnamanRegister();
	for (int i = 0; i < ent.size(); i++) {
		entities.add(new SelectItem(ent.get(i)));
	}
	return entities;
}*/

//AnamanRegisterEntityDTO entity = new AnamanRegisterEntityDTO();



// Actions
// ------------------------------------------------------------------------------------

/*public void action() {
	System.out.println("Selected AnamanRegisterService item: "
			+ selectedItem);
}*/

// Getters
// ------------------------------------------------------------------------------------
public List<SelectItem> getEntities() {
	List<SelectItem> entities = new ArrayList<SelectItem>();
	for (int i = 0; i < entityList.size(); i++) {
		entities.add(new SelectItem(entityList.get(i)));
	}
	return entities;
}

// Setters
// ------------------------------------------------------------------------------------
public void setEntities(List<SelectItem> entities) {
	this.entities = entities;
}

}[/code]

Espero ter ajudado um pouco mais :slight_smile:
Gustavo

[quote=andreihirata]alexegidio a PROPRIEDADE Sugestion é apenas para mostrar sugestões.Ou seja. Quando a pessoa estiver digitando PED, e estiver no beam a palavra PEDRA,
automaticamente sera mostrada a palavra PEDRA para o usuario.É como fosse o search do google…

Pelo que estou vendo aqui.O problema n está no jsp e sim na hora de chamar os valores pelo bean.[/quote]
Ih! Foi mal …
Realmente é verdade … eu achei que essa propriedade fosse semelhante ao “value” em h:selectOneMenu
Isso que dá não ler a documentação direito

Antes de eu dar uma solução.Faz o seguinte.Ao invez de usar o componente rich combo box.Substitua por um <h:selectOneMenu
Exemplo como deve ficar.Se n der,Ae eu vejo mais tarde o problema

<h:selectOneMenu id="Sele"
                                         required="True"
                                         value="#{tiposAcaoC.tiposAcao.idNaturezasAcao}" //Aqui é aonde eu salvo o valor capturado,que seria o id do objeto
                                         label="OI"
                                         immediate="false"
                         >
                            <f:selectItems value="#{tiposAcaoC.buscarNaturezasAcao}" />// aqui executo um bean trazendo os valores que eu quero no combo
                        </h:selectOneMenu>

Faça um favor ae…Debuga a linha que vou deixar em negrito.Verifica se está entrando dentro do for…Porq acredito que o erro vai ocorrer ae.pelo que to vendo ae, nao esta conseguindo alimentar a lista.

public class AnamanRegisterMB {

// Init

// ---------------------------------------------------------------------------------------

private AnamanRegisterService ars = AnamanRegisterService.getInstance();

private List entities;

//private AnamanRegisterService selectedItem;

private List entityList = ars.getRegisterEntityList();

/*public ArrayList getEntities() {

//List entityList = new LinkedList();

List ent = ars.getRegisterEntityList();

//AnamanRegister entity = new AnamanRegister();

for (int i = 0; i < ent.size(); i++) {

entities.add(new SelectItem(ent.get(i)));

}

return entities;

}*/

//AnamanRegisterEntityDTO entity = new AnamanRegisterEntityDTO();

// Actions

// ------------------------------------------------------------------------------------

/*public void action() {

System.out.println("Selected AnamanRegisterService item: "

+ selectedItem);

}*/

// Getters

// ------------------------------------------------------------------------------------

public List getEntities() {

[b]# List entities = new ArrayList();

for (int i = 0; i < entityList.size(); i++) {

entities.add(new SelectItem(entityList.get(i)));

} [/b]

return entities;

}

consegui fazer funcionar!

deixei o método assim:

public List<SelectItem> getEntities() { List<SelectItem> entities = new ArrayList<SelectItem>(); List entityList = ars.getRegisterEntityList(); for (int i = 0; i < entityList.size(); i++) { AnamanRegisterEntityDTO entity = new AnamanRegisterEntityDTO(); entity.setEntityName(String.valueOf(entityList.get(i))); entities.add(new SelectItem(entity)); } return entities; }
e, no AnamanRegisterEntityDTO, sobrescrevi um toString() assim:

@Override public String toString() { return entityName; }

modifiquei também o combobox, deixando-o assim:

<rich:comboBox defaultLabel="#{bundle['anamanRegisterServiceJSP.selectEntity']}" width="300" listHeight="100px" value="#{anamanRegisterServiceMB.selectedEntity}" > <f:selectItems value="#{anamanRegisterServiceMB.entities}" /> </rich:comboBox>

minha idéia é que o valor selecionado no combo, seja capturado pela propriedade selectedEntity (string) para que eu possa usar isso no próximo filtro. Essa minha lógica faz sentido? ou eu devo usar um onSelected ou action?

Gustavo

[b]minha idéia é que o valor selecionado no combo, seja capturado pela propriedade selectedEntity (string) para que eu possa usar isso no próximo filtro. Essa minha lógica faz sentido? ou eu devo usar um onSelected ou action?

Gustavo [/b]

Deixa eu ver se entendi.Vc quer armazenar o valor escolhido pelo usuario no combo e granvar ele em uma string usando a função selectedEntity.Este próximo filtro, seria outro combo box?Ou seja.Um combo box estado SP, ativa outro combo box cidade e lista todas cidade do estado de SP?
Se for isto, eu concordo com vc.Apesar que pegar o codigo do combo sera a melhor alternativa.
é isto que vc está falando? no caso o primeiro combox box use onchange ou onclick.

sim, o próximo filtro é o próximo combo. o valor selecionado no primeiro combo volta armazenado em selectedEntity, certo? penso que esse selectedEntity tem que ser passado como parâmetro para popular um outro combo, criado da seguinte maneira:

[code] public List getRefTypes() {
if (selectedEntity ==null)
selectedEntity = “ANVISA”; // para garantir que o segundo combo seja carregado
List refTypes = new ArrayList();
List refTypeListByEntity = ars.getRegisterRefTypeListByEntity(selectedEntity);
for (int i = 0; i < refTypeListByEntity.size() ; i++) {
AnamanRegisterRefDTO ref = new AnamanRegisterRefDTO();
refTypes.add(new SelectItem(new String(ref.getRef() + " - " + ref.getType())));
}
return refTypes;
}

public void setRefTypes(List refTypes) {
this.refTypes = refTypes;
}
[/code]

O valor que aparece no segundo combo é uma composição, isso funciona, né?

Gustavo

Olha .Se funciona só testando.O que eu faria seria assim.Levando em consideração o que voce já fez.

Pegaria esta string.E faria uma jquery passando o parametro com esta string.Gravaria os dados em uma Lista, e alimentaria este segundo combo.Isto ficaria muito mais bonito tambem na hora de dar manutenção.