Pegar objeto de um rich:comboBox

124 views
Skip to first unread message

Sérgio Fantin

unread,
Mar 9, 2009, 4:54:42 PM3/9/09
to javasf: JavaServer Faces International Group
Olá pessoal,

tenho um rich:comboBox que está preenchido com uma lista de objetos. O
que preciso fazer é pegar o id do objeto que foi escolhido. Segue o
código: <rich:comboBox id="subCategoria" suggestionValues="#
{categoriaFace.subcategorias}" rendered="true"/>

Tentei criar uma váriavel daquelas que usamos em tables, tipo:
<rich:comboBox var="subCategoria" id="subCategoria" suggestionValues="#
{categoriaFace.subcategorias}" rendered="true"/>

mas o componente não aceita essa opção.

Como eu faço pra pegar o id do objeto escolhido?

Rafael de Paula Souza

unread,
Mar 9, 2009, 5:14:13 PM3/9/09
to jav...@googlegroups.com
<rich:comboBox value="#{bean.objeto.id}" id="subCategoria"
  rendered="true">
    <f:selectItems value="#{categoriaFace.subcategorias}"/>
</rich:comboBox>

Sendo que subcategorias é uma lista de SelectItem. Com o JSF puro não é possível (ainda) você passar o objeto inteiro como parâmetro, para isso você pode usar um entity converter http://www.rponte.com.br/2008/07/26/entity-converters-pra-da-e-vender/

2009/3/9 Sérgio Fantin <sergio.l...@gmail.com>



--
Rafael de Paula Souza

Sublimus - Desenvolvimento de Software e Soluções Web.
www.sublimus.com.br


Sérgio Fantin

unread,
Mar 10, 2009, 7:57:50 AM3/10/09
to jav...@googlegroups.com
Olá Rafael,

se eu colocar value="#{bean.objeto.id}" no meu combo, aparece os ids dos objetos. Daí quando eu escolho algum deles eu recebo uma exception: Caused by:
java.lang.IllegalArgumentException - Cannot convert Bebidas Argentinas of type class br.com.sistema.entidades.SubCategoria to class java.lang.Long

Se eu troco pra value="#{bean.objeto.nome}" eu recebo outra exception de cara, nem mostra a página: Caused by: java.lang.ClassCastException - java.lang.String cannot be cast to br.com.sistema.conversor.BaseEntity

Segue o código:

<h:outputLabel for="subCategoria" value="Subcategoria " styleClass="rotulos"/>
        <a4j:region immediate="true" renderRegionOnly="true">
            <rich:comboBox id="subCategoria" value="#{categoriaFace.subCategoria.id}" converter="simpleEntityConverter" styleClass="edit" defaultLabel="Escolha a subcategoria" width="159" rendered="true">
                <f:selectItems value="#{categoriaFace.subcategoriasByCategoriaId}"/>
            </rich:comboBox>
   
            <h:commandButton value="Listar" action="#{categoriaFace.getSubParametrosBySubCategoriaId}" styleClass="botoes">
                    <f:setPropertyActionListener target="#{categoriaFace.selectedSubCategoriaId}" value="#{categoriaFace.subCategoria.id}" />
            </h:commandButton>
        </a4j:region>

Valew

2009/3/9 Rafael de Paula Souza <rafae...@gmail.com>

Rafael de Paula Souza

unread,
Mar 10, 2009, 11:28:32 AM3/10/09
to jav...@googlegroups.com
Se você está usando o simpleEntityConverter acredito que tenha que ser assim:

<rich:comboBox id="subCategoria" value="#{categoriaFace.subCategoria}" converter="
simpleEntityConverter" styleClass="edit" defaultLabel="Escolha a subcategoria" width="159" rendered="true">
                <f:selectItems value="#{categoriaFace.subcategoriasByCategoria}"/>
            </rich:comboBox>


Sendo que o subcategoriasByCategoria tem que retornar uma List<SelectItem> com os values com a referência do objeto inteiro.

Mais uma dica:

Não faça assim:


  <h:commandButton value="Listar" action="#{categoriaFace.
getSubParametrosBySubCategoriaId}" styleClass="botoes">
                    <f:setPropertyActionListener target="#{categoriaFace.selectedSubCategoriaId}" value="#{categoriaFace.subCategoria.id}" />
            </h:commandButton>

Faça assim:

  <h:commandButton value="Listar" action="#{categoriaFace.
getSubParametrosBySubCategoriaId}" styleClass="botoes">
                    <f:setPropertyActionListener target="#{categoriaFace.selectedSubCategoria}" value="#{categoriaFace.subCategoria}" />
            </h:commandButton>

Passe o objeto todo como parâmetro.


2009/3/10 Sérgio Fantin <sergio.l...@gmail.com>

Sérgio Fantin

unread,
Mar 10, 2009, 2:35:56 PM3/10/09
to jav...@googlegroups.com
Rafael,

eu acho que agora que eu fui captar...

Ao invés de usar private Long selectedCategoriaId eu devo usar private Categoria selectedCategoria = new Categoria(), pois terei o objeto "inteiro". Daí fica fácil escolher qual atributo dele usar.

É isso mesmo?!

Abraços...


2009/3/10 Rafael de Paula Souza <rafae...@gmail.com>

Rafael de Paula Souza

unread,
Mar 10, 2009, 6:50:26 PM3/10/09
to jav...@googlegroups.com
Isso, no caso do setPropertyActionListener isso é aceito sem nenhuma "gambiarra". Já no caso do comboBox tu precisa usar o entity converter ou passar só o ID como referência.

2009/3/10 Sérgio Fantin <sergio.l...@gmail.com>

Sérgio Fantin

unread,
Mar 11, 2009, 8:04:37 AM3/11/09
to jav...@googlegroups.com
Assim ficou fácil de se trabalhar.

Mudei meu código, agora ficou assim:

    <!--  categorias -->
        <h:outputLabel for="categoria" value="Categoria " styleClass="rotulos"/>
        <h:selectOneMenu id="categoria" value="#{categoriaFace.categoria.id}" converter="simpleEntityConverter" rendered="true">
            <f:selectItems value="#{categoriaFace.categorias}"/>
            <a4j:support event="onchange" ajaxSingle="true" action="#{categoriaFace.subcategoriasByCategoria}" reRender="categoria,subcategoria"/>
        </h:selectOneMenu>
       
        <!-- subcategorias -->
        <h:outputLabel for="subcategoria" value="Subcategoria " styleClass="rotulos"/>
        <h:selectOneMenu id="subcategoria" value="#{categoriaFace.subCategoria.id}" converter="simpleEntityConverter" rendered="true">

              <f:selectItems value="#{categoriaFace.subcategoriasByCategoria}"/>
        </h:selectOneMenu>

É aquele esquema de combos aninhados. Quando o usuário clicar no primeiro combo, eu preciso que o id da Categoria selecionada seja enviada pro meu MB para que as SubCategorias relacionadas a ela sejam listadas (método subcategoriasByCategoria).
Mas eu não queria de um botão para isso, queria que fosse feito com a4j. Do jeito que o código está ele só está preenchendo primeiro combo. E os dois sysouts do método imprimem null:

public List<SelectItem> getSubcategoriasByCategoria(){
        Session session = HibernateUtil.currentSession();
        CategoriaDAO dao = new CategoriaDAO(session);

        List<SelectItem> items = new ArrayList<SelectItem>();
       
        for(SubCategoria subcat : dao.pesquisaSubcategoriasByCategoriaId(this.selectedCategoria.getId())){
            items.add(new SelectItem(subcat, subcat.getNome()));
        }
       
        System.out.println("*** lista subCategorias >>> " + subCategorias);
        
        System.out.println("*** selectedSubCategoria >>> " + this.selectedSubCategoria);
       
        return items;
    }


Pode dar uma luz?

Agradeço antecipadamente!

Rafael de Paula Souza

unread,
Mar 11, 2009, 8:16:39 PM3/11/09
to jav...@googlegroups.com
O Bean tá em request?


2009/3/11 Sérgio Fantin <sergio.l...@gmail.com>

Sérgio Fantin

unread,
Mar 12, 2009, 7:42:29 AM3/12/09
to jav...@googlegroups.com
Deu certo. Funcionou! Esquecei de postar!

O bean está com o escopo de session. É isso mesmo?

Abraço...

2009/3/11 Rafael de Paula Souza <rafae...@gmail.com>

Bruno maomeH

unread,
Mar 12, 2009, 7:55:56 AM3/12/09
to jav...@googlegroups.com
nunca é legal deixar seus beans com escopo de sessão (salvo exeções)..
procure saber sobre componentes que aumentam o escopo de request..
a4j:keepAlive, t:saveState, myFaces Orchestra..
eles criam um escopo maior que request e menor q session

2009/3/12 Sérgio Fantin <sergio.l...@gmail.com>



--
   C. SOARES - Bruno,
   C. COMPUTAÇÃO - Unifor,
   C. MAGALHÃES - Desenvolvedor.

Rafael de Paula Souza

unread,
Mar 12, 2009, 1:50:30 PM3/12/09
to jav...@googlegroups.com
Sergio é isso que o Bruno falou.
No teu caso usa o a4j:keepAlive e podes deixar o bean em request.

Rafael Ponte

unread,
Mar 13, 2009, 7:54:02 PM3/13/09
to jav...@googlegroups.com
Eu realmente não vou com a cara do a4j:keepAlive :)) Já tive alguns problemas bizarros com ele quando usei a abordagem "orientada a estados". Além do mais, não gosto de "persistir" o managed bean inteiro [apenas preferência - e o t:saveState não combina muito com isso!].

No mais, procure algum framework de escopo conversacional maior que request.

2009/3/12 Rafael de Paula Souza <rafae...@gmail.com>



--
Rafael Ponte
http://www.rponte.com.br

Matheus Fechine

unread,
Mar 15, 2009, 8:54:34 PM3/15/09
to jav...@googlegroups.com
Quando preciso salvar um objeto na sessão com um escopo menor que a session e maior que o request, uso o getPageFlowScope() do Trinidad...

Abaixo segue um exemplo que poderia ser utilizado.

    /**
     * Atribui os objeto de pesquisa no pageFlowScope.
     * @id - identificador do objeto
     * @result - objeto
     */
    public void setPageFlowScope(String id, Object result) {       
        RequestContext.getCurrentInstance().getPageFlowScope().put(id,result);
    }

    /**
     * Retorna um objeto armazenada no escopo de fluxo de página. PageSlowScope.
     * @return
     */
    public Object getPageFlowScope(String id) {
        return  RequestContext.getCurrentInstance().getPageFlowScope().get(id);
    }


o <t:saveState> nem sempre funciona, como o Rafael Ponte falou, e nunca confio muito nele..

Att,

Matheus Fechine de Moura

2009/3/13 Rafael Ponte <rpo...@gmail.com>

Rafael Ponte

unread,
Mar 16, 2009, 7:28:12 AM3/16/09
to jav...@googlegroups.com
Na verdade é o contrário, quem nem sempre funciona é o pageFlowScope do Trinidad :))

2009/3/15 Matheus Fechine <matheu...@gmail.com>

Matheus Fechine

unread,
Mar 16, 2009, 8:46:54 AM3/16/09
to jav...@googlegroups.com
O_O
 
Pois comigo sempre funfou :P
 
Mas como é vc q ta dizendo então eu acredito :)

2009/3/16 Rafael Ponte <rpo...@gmail.com>

Rafael Ponte

unread,
Mar 16, 2009, 9:01:17 AM3/16/09
to jav...@googlegroups.com
O pageflowscope funciona bem, mas a partir do momento que o número de dialogs [indepentende se modal, popup ou "tela inteira"] aumenta em telas mais complexas ele começa a "endoidar" e perde alguns escopos sem explicações.

Não entendi bem o problema, pois até hoje não tive tempo de investigar. Nesses casos eu corro pro t:saveState e fico feliz :))

2009/3/16 Matheus Fechine <matheu...@gmail.com>

Sérgio Fantin

unread,
Mar 17, 2009, 8:09:58 AM3/17/09
to jav...@googlegroups.com
Ae pessoal,

quando eu coloco o escopo em session eu consigo pegar o id tão sonhado. hehe...

Mas vou acabar mudando pra request pra não ter problemas futuros.

Estou pensando em usar o a4j:keepAlive por eu já ter ele no meu classpath. Alguém tem algum exemplo prático de como usá-lo? Pode ser alguma coisa simples mesmo.

Ah... segue o código pra vocês verem como ficou:                

<!--  categorias -->
                <h:outputLabel for="categoria" value="Categoria " styleClass="rotulos" />
                <h:selectOneMenu id="categoria"    value="#{categoriaFace.categoria.id}" rendered="true">

                    <f:selectItems value="#{categoriaFace.categorias}" />
                    <a4j:support event="onchange" ajaxSingle="false" action="#{categoriaFace.actionCarregaComboSubcategoria}" reRender="categoria,subcategoria,tableParams" />
                </h:selectOneMenu>

                <!-- parametros -->
                <h:outputText value="Parâmetros" />
                <rich:dataTable value="#{categoriaFace.parametrosByCategoria}" var="parametro" rendered="true" rows="5" id="tableParams" width="30%" cellspacing="0" cellpadding="0" border="0">
                    <h:column>
                        <h:outputText value="#{parametro.nome}" />
                    </h:column>
                    <h:column>
                        <h:outputText value="#{parametro.escolhido}" />
                        <h:selectBooleanCheckbox value="true" id="checkBoxParam" />
                    </h:column>
                </rich:dataTable>

                <f:verbatim><br/></f:verbatim>

                <!-- sub categorias -->
                <h:outputLabel for="subcategoria" value="Sub categoria " styleClass="rotulos"  />
                <h:selectOneMenu id="subcategoria" value="#{categoriaFace.subCategoria.id}" rendered="true">
                     <f:selectItems value="#{categoriaFace.subCategorias}" />
                     
                     <a4j:support event="onchange" ajaxSingle="false" action="#{categoriaFace.actionCarregaComboSubcategoria}" reRender="tableSubParams"/>
                       
                </h:selectOneMenu>

                <f:verbatim><br /></f:verbatim>

                <!-- sub parametros -->
                <h:outputText value="Sub Parâmetros" />
                <rich:dataTable value="#{categoriaFace.subParametrosBySubCategoria}" var="subParametro" rendered="true" rows="5" id="tableSubParams" width="30%" cellspacing="0" cellpadding="0" border="0">
                    <h:column>
                        <h:outputText value="#{subParametro.nome}" />
                    </h:column>

                    <h:column>
                        <h:outputText value="#{subParametro.escolhido}" />
                        <h:selectBooleanCheckbox value="true" id="checkBoxSubParam" />
                    </h:column>

                </rich:dataTable>

Abraços...


2009/3/16 Rafael Ponte <rpo...@gmail.com>

Bruno maomeH

unread,
Mar 17, 2009, 8:45:13 AM3/17/09
to jav...@googlegroups.com
<a4j:keepAlive beanName="teuBean" />
:P

2009/3/17 Sérgio Fantin <sergio.l...@gmail.com>

Bruno maomeH

unread,
Mar 17, 2009, 8:45:55 AM3/17/09
to jav...@googlegroups.com
e o teu bean tem que implementar a interface Serializable

Sérgio Fantin

unread,
Mar 17, 2009, 9:03:50 AM3/17/09
to jav...@googlegroups.com
Hehe... boa!

Fabiano Almeida

unread,
Mar 24, 2009, 11:36:41 AM3/24/09
to javasf: JavaServer Faces International Group
Pessoal,

Eu estou tendo o mesmo problema de pegar os objetos dentro de um
rich:combobox.
Não gostaria de sair dessa solução pelo componente que está sendo
disponibilizado pelo RichFaces.
Li o artigo de Rafael Ponte e achei interessante a aplicabilidade dos
Convertes, mas não ficou muito claro, para quem nunca utilizou e nunca
ouviu falar, como eu poderia aplicar na minha aplicação essa solução
dos Converters.
Alguém poderia me dar uma luz?

De antemão, muito obrigado.

On 17 mar, 10:03, Sérgio Fantin <sergio.lnd.fan...@gmail.com> wrote:
> Hehe... boa!
>
> 2009/3/17 Bruno maomeH <bsoares.i...@gmail.com>
>
> > e o teu bean tem que implementar a interface Serializable
>
> > 2009/3/17 Bruno maomeH <bsoares.i...@gmail.com>
>
> > <a4j:keepAlive beanName="teuBean" />
> >> :P
>
> >> 2009/3/17 Sérgio Fantin <sergio.lnd.fan...@gmail.com>
>
> >> Ae pessoal,
>
> >>> quando eu coloco o escopo em *session* eu consigo pegar o id tão
> >>> sonhado. hehe...
>
> >>> Mas vou acabar mudando pra *request* pra não ter problemas futuros.
> >>>> 2009/3/16 Matheus Fechine <matheusfmo...@gmail.com>
>
> >>>> O_O
>
> >>>>> Pois comigo sempre funfou :P
>
> >>>>> Mas como é vc q ta dizendo então eu acredito :)
>
> >>>>> 2009/3/16 Rafael Ponte <rpo...@gmail.com>
>
> >>>>> Na verdade é o contrário, quem nem sempre funciona é o pageFlowScope do
> >>>>>> Trinidad :))
>
> >>>>>> 2009/3/15 Matheus Fechine <matheusfmo...@gmail.com>
> >>>>>>>> 2009/3/12 Rafael de Paula Souza <rafael....@gmail.com>
>
> >>>>>>>> Sergio é isso que o Bruno falou.
> >>>>>>>>> No teu caso usa o a4j:keepAlive e podes deixar o bean em request.
>
> >>>>>>>>> 2009/3/12 Bruno maomeH <bsoares.i...@gmail.com>
>
> >>>>>>>>> nunca é legal deixar seus beans com escopo de sessão (salvo
> >>>>>>>>>> exeções)..
> >>>>>>>>>> procure saber sobre componentes que aumentam o escopo de request..
> >>>>>>>>>> a4j:keepAlive, t:saveState, myFaces Orchestra..
> >>>>>>>>>> eles criam um escopo maior que request e menor q session
>
> >>>>>>>>>> 2009/3/12 Sérgio Fantin <sergio.lnd.fan...@gmail.com>
>
> >>>>>>>>>> Deu certo. Funcionou! Esquecei de postar!
>
> >>>>>>>>>>> O bean está com o escopo de session. É isso mesmo?
>
> >>>>>>>>>>> Abraço...
>
> >>>>>>>>>>> 2009/3/11 Rafael de Paula Souza <rafael....@gmail.com>
>
> >>>>>>>>>>> O Bean tá em request?
>
> >>>>>>>>>>>> 2009/3/11 Sérgio Fantin <sergio.lnd.fan...@gmail.com>
>
> >>>>>>>>>>>> Assim ficou fácil de se trabalhar.
>
> >>>>>>>>>>>>> Mudei meu código, agora ficou assim:
>
> >>>>>>>>>>>>>     <!--  categorias -->
> >>>>>>>>>>>>>         <h:outputLabel for="categoria" value="Categoria "
> >>>>>>>>>>>>> styleClass="rotulos"/>
> >>>>>>>>>>>>>         <h:selectOneMenu id="categoria" value="#{
> >>>>>>>>>>>>> categoriaFace.categoria.id<http://categoriaface.categoria.id/>}"
> >>>>>>>>>>>>> converter="simpleEntityConverter" rendered="true">
> >>>>>>>>>>>>>             <f:selectItems
> >>>>>>>>>>>>> value="#{categoriaFace.categorias}"/>
> >>>>>>>>>>>>>             <a4j:support event="onchange" ajaxSingle="true"
> >>>>>>>>>>>>> action="#{categoriaFace.subcategoriasByCategoria}"
> >>>>>>>>>>>>> reRender="categoria,subcategoria"/>
> >>>>>>>>>>>>>         </h:selectOneMenu>
>
> >>>>>>>>>>>>>         <!-- subcategorias -->
> >>>>>>>>>>>>>         <h:outputLabel for="subcategoria" value="Subcategoria "
> >>>>>>>>>>>>> styleClass="rotulos"/>
> >>>>>>>>>>>>>         <h:selectOneMenu id="subcategoria" value="#{
> >>>>>>>>>>>>> categoriaFace.subCategoria.id<http://categoriaface.subcategoria.id/>}"
> >>>>>>>>>>>>> converter="simpleEntityConverter" rendered="true">
> >>>>>>>>>>>>>               <f:selectItems
> >>>>>>>>>>>>> value="#{categoriaFace.subcategoriasByCategoria}"/>
> >>>>>>>>>>>>>         </h:selectOneMenu>
>
> >>>>>>>>>>>>> É aquele esquema de combos aninhados. Quando o usuário clicar
> >>>>>>>>>>>>> no primeiro combo, eu preciso que o *id da Categoria*selecionada seja enviada pro meu MB para que as
> >>>>>>>>>>>>> *SubCategorias* relacionadas a ela sejam listadas (método *
> >>>>>>>>>>>>> subcategoriasByCategoria*).
> >>>>>>>>>>>>> Mas eu não queria de um botão para isso, queria que fosse feito
> >>>>>>>>>>>>> com a4j. Do jeito que o código está ele só está preenchendo primeiro combo.
> >>>>>>>>>>>>> E os dois sysouts do método imprimem null:
>
> >>>>>>>>>>>>> public List<SelectItem> *getSubcategoriasByCategoria*(){
> >>>>>>>>>>>>>         Session session = HibernateUtil.currentSession();
> >>>>>>>>>>>>>         CategoriaDAO dao = new CategoriaDAO(session);
>
> >>>>>>>>>>>>>         List<SelectItem> items = new ArrayList<SelectItem>();
>
> >>>>>>>>>>>>>         for(SubCategoria subcat :
> >>>>>>>>>>>>> dao.pesquisaSubcategoriasByCategoriaId(this.selectedCategoria.getId())){
> >>>>>>>>>>>>>             items.add(new SelectItem(subcat,
> >>>>>>>>>>>>> subcat.getNome()));
> >>>>>>>>>>>>>         }
>
> >>>>>>>>>>>>>         *System.out.println("*** lista subCategorias >>> " +
> >>>>>>>>>>>>> subCategorias);
> >>>>>>>>>>>>> *
> >>>>>>>>>>>>>         *System.out.println("*** selectedSubCategoria >>> " +
> >>>>>>>>>>>>> this.selectedSubCategoria);*
>
> >>>>>>>>>>>>>         return items;
>
> ...
>
> mais »

Sérgio Fantin

unread,
Mar 24, 2009, 12:56:41 PM3/24/09
to jav...@googlegroups.com
Fala, Fabiano.

Eu consegui passar o id do obj escolhido no combo pro meu MB, mas só o id. Se quiser eu te mando o código. O jeito mais elegante de fazer isso é passando o objeto completo pro MB, pois você pode pegar qualquer atributo que quiser. Isso eu não consegui até agora. :( Eu acho que usei o converter do Rafael de forma errada, pois estava dando nullPointer. Aí eu criei um converterTabajaraDoSerjaum e parou de dar nullPointer:

public class ConverterCategoria implements Converter {

    public Object getAsObject(FacesContext context, UIComponent component, String name)    throws ConverterException {
        Categoria categoria = new Categoria();
        categoria.setNome(name);
   
        return categoria;
    }

    public String getAsString(FacesContext context, UIComponent component, Object classCategoria) throws ConverterException {
        if(classCategoria == null){
            return "Categoria sem nome";
        }
   
        Categoria categoria = (Categoria) classCategoria;
        return categoria.getNome();
    }
}

Não esqueça de sobrescrever o equals/hashCode e registrar o converter no seu faces-config.xml.

Abraços...




2009/3/24 Fabiano Almeida <fabiano...@gmail.com>
Reply all
Reply to author
Forward
0 new messages