Selectonemenu + a4j:support não funciona

12 respostas
L

Pessoal depois de muita pesquisa, muito quebrar a cabeça decidi abrir um tópico para tentar obter ajuda pra solucionar meu problema.
Não estou conseguindo fazer funcionar dois dependentes (estados e cidades) simples não?? mas não funciona…

Estou usando richfaces e facelets

O código do meu formulário no meu arquivo cadCliente.xhtml

<a4j:form>
                                <rich:panel header="Cadastro de Cliente" style="width: 615px">
                                    <span jsfc="h:messages" showSummary="true" showDetail="true" style="color:green; font-size: 10px"/>
                                    <br/>     <h:outputText value="Endereço " size="20" style="font-weight:bold; font-size: 12px" />
                                    <rich:separator height="2" lineType="double"/><br/>
                                    <h:panelGrid columns="2" id="panel2" columnClasses="odd-row,even-row">
                                        <h:outputText value="Uf" />
                                        <h:column>
                                        <a4j:region>
                                            <h:selectOneMenu id="estado" value="#{estadoJPA.codestado}" immediate="true">
                                                <f:selectItems value="#{estadoJPA.itemsEstado}"/>
                                                <a4j:support event="onchange" ajaxSingle="true" reRender="cidade" action="#{cidadeJPA.trocaCidadesEstado}"/>
                                            </h:selectOneMenu>
                                        </a4j:region>
                                            <br/>
                                        </h:column>
                                        <h:outputText value="Cidade" />
                                        <h:column>
                                            <a4j:region>
                                            <h:selectOneMenu var="cidade" id="cidade" value="#{cidadeJPA.codcidade}" >
                                                <f:selectItems value="#{cidadeJPA.itemsCidade}"/>
                                            </h:selectOneMenu>
                                            </a4j:region>
                                            <br/>
                                        </h:column>                   
                                        
                                    </h:panelGrid>
                                </rich:panel>
                    </a4j:form>

O código que popula o select de ufs no meu Bean:

public List getListaEstados() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        listaEstados = em.createNamedQuery("Estado.findAll").getResultList();
        em.close();
        return listaEstados;
    }

    List<SelectItem> itemsEstado;

    public List<SelectItem> getitemsEstado() {
        EstadoJpaController estJPA = new EstadoJpaController();
        List<Estado> estados = estJPA.getListaEstados();
        List<SelectItem> cadastro = new ArrayList<SelectItem>();
        for (Estado est : estados) {
            SelectItem itens = new SelectItem(est.getCodestado(), est.getDescricao());
            cadastro.add(itens);
        }
        return cadastro;
    }

O código que popula o select de cidades e que deveria atualiza-lo, no meu Bean:

public List getlistaCidades() {
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        listaCidades = em.createNamedQuery("Cidade.findAll").getResultList();
        em.close();
        return listaCidades;
    }
    public List<SelectItem> itemsCidade;

    public List<SelectItem> getitemsCidade() {
        CidadeJpaController cidJPA = new CidadeJpaController();
        List<Cidade> cidades = cidJPA.getlistaCidades();
        List<SelectItem> cadastro = new ArrayList<SelectItem>();
        for (Cidade cids : cidades) {
            SelectItem itens = new SelectItem(cids.getCodcidade(), cids.getDescricao());
            cadastro.add(itens);
        }
        return cadastro;
    }

    List<Cidade> encontrarCidadesPorEstado(String codEstado) {
        EntityManager em = getEntityManager();
            Query q = em.createNamedQuery("Cidade.findByCodestado");
            q.setParameter("codestado", Integer.parseInt(codEstado));
            em.close();
            return q.getResultList();  
    }

    public void trocaCidadesEstado(ValueChangeEvent event) {
// garantindo que o valor do combo de estados mudou
        if (event.getNewValue() != event.getOldValue()) {
            CidadeJpaController cidJPA = new CidadeJpaController();
            List<SelectItem> selectestado = new ArrayList<SelectItem>();
            List<Cidade> cidade = cidJPA.encontrarCidadesPorEstado(event.getNewValue().toString());
            for (Cidade cid : cidade) {
                SelectItem itens = new SelectItem(cid.getCodcidade(), cid.getDescricao());
                selectestado.add(itens);
            }
                this.itemsCidade = selectestado;
        }
    }

Os dois selects são populados perfeitamente, mas o meu select de cidades não atualiza quando altero o de estados, ele continua com a listagem normal, com todas as cidades.

Quem tiver qualquer idéia do que pode ser, fico grato.

12 Respostas

J

Coloca no teu selectOneMenu um valueChangeListener…
e cria esse metodo no teu bean
e pelo teu bean tu acessa esse metodo de alterar e tira o immediate! nao é necessario!

Criando pelo valueChangeListener acho que ele é preenchido corretamento os dois a qlqer alteração!

Se tu nao conseguir implementar até denoite te deixo o codigo aqui!

L

Jonathan, retirei o action do a4j:support e coloquei a ação em um valuechangelistener no selectonemenu de estados e retirei o immediate.

<a4j:form>
                                <rich:panel header="Cadastro de Cliente" style="width: 615px">
                                    <span jsfc="h:messages" showSummary="true" showDetail="true" style="color:green; font-size: 10px"/>
                                    <br/>     <h:outputText value="Endereço " size="20" style="font-weight:bold; font-size: 12px" />
                                    <rich:separator height="2" lineType="double"/><br/>
                                    <h:panelGrid columns="2" id="panel2" columnClasses="odd-row,even-row">
                                        <h:outputText value="Uf" />
                                        <h:column>
                                        <a4j:region>
                                            <h:selectOneMenu id="estado" value="#{estadoJPA.codestado}" valueChangeListener="#{cidadeJPA.trocaCidadesEstado}">
                                                <f:selectItems value="#{estadoJPA.itemsEstado}"/>
                                                <a4j:support event="onchange" ajaxSingle="true" reRender="cidade"/>
                                            </h:selectOneMenu>
                                        </a4j:region>
                                            <br/>
                                        </h:column>
                                        <h:outputText value="Cidade" />
                                        <h:column>
                                            <a4j:region>
                                            <h:selectOneMenu id="cidade" value="#{cidadeJPA.codcidade}" >
                                                <f:selectItems value="#{cidadeJPA.itemsCidade}"/>
                                            </h:selectOneMenu>
                                            </a4j:region>
                                            <br/>
                                        </h:column>                   
                                        
                                    </h:panelGrid>
                                </rich:panel>
                    </a4j:form>

mas continua sem funcionar…

o meu bean continua igual com o metodo trocaCidadesEstado e que chama o encontrarCidadesPorEstado que acredito estarem corretos, filtrando as cidades.

L

alguma luz?

J

ba… fiquei de te deixa o codigo e nao deixei … hehe

malz

te deixo agora detarde qdo chega em casa sem falta… VALEU

G

alguns comportamentos do A4J não são executados dependendo so tipo do componente.

no caso do combobox (select one menu) vc pode usar o event=“onclick” ou event=“onmousedown” (recomendo)

os eventos onselect ou onchange não costumam funcionar (obs.: isso pode variar de acordo com a versão das suas bibliotecas)

L

Giulliano:
alguns comportamentos do A4J não são executados dependendo so tipo do componente.

no caso do combobox (select one menu) vc pode usar o event=“onclick” ou event=“onmousedown” (recomendo)

os eventos onselect ou onchange não costumam funcionar (obs.: isso pode variar de acordo com a versão das suas bibliotecas)

Giulliano, tentei das duas formas, sem sucesso… tinha pensado em algo semelhante, talvez em algum bug,tah dificil… mas vlw pela ideia.
Vou esperar o codigo do Jonathan mais tarde pra ver se resolvo de vez, jah virou questão de honra, tah muito dificil esse codigozinho :stuck_out_tongue:

J

Leo

procurei o codigo la em casa e achei apenas com o <h:selectOneMenu />

Agora que me lembrei que tentei pelo richfaces e tava com bug…
mais eu tinha achado um na net sem bug… mais nao me lembro se era do richfaces…

Se eu acha denovo te encaminho o link

Valeu :?

J

Achei o link:
http://serjaum.wordpress.com/2009/08/28/jsf-tutorial-combos-aninhados-estadoscidades/#more-741

Ele utiliza o a4j

mais nao pra o selectOneMenu

FEITO :thumbup:

G

Cara vc pode tentar o seguinte…cria um PanelGroup e dá um ID para ele.

põe o seu combo de cidades dentro desse panel e tira esse ajaxregion…depois vc manda o reRender atualizar o ID do PanelGroup.

O ReRender é cheio dos bugs tb…normalmente eu mandava ele atualizar um panelGroup (que é equivalente a uma div) e não dava erro.

L

Seu código postado inicialmente está correto, basta retirar o immediate=“true” do selectOneMenu. Esse atributo é utilizado para “pular” as fases de conversão e validação do ciclo de vida do JSF, mas ele também faz com que os dados do model (managed bean) não sejam atualizados.

Ao contrário do que foi dito anteriormente o evento “onchange” funciona sim para o h:selectOneMenu

A

Eu estava com problema para fazer o reRender do selectOneMenu e consegui resolver realizando uma alteração pequena alteração que confesso não sei por que deu certo!!!:smiley:

O código abaixo está dentro de um pickList

<a4j:support event="onlistchange" action="#qualquerBean.limpaCampo}" reRender="idSelectOneMeny" />

Mudei o código acima para o logo abaixo

<a4j:support event="onlistchange" ajaxSingle="true" action="#{qualquerBean.limpaCampo}" reRender="idSelectOneMeny" />

engraçado que se o id do campo que estou usando pertencer a um pickList funciona sem colocar ajaxSingle=“true”

L

Usando ajaxSingle=“true” o único componente que será processado (convertido, validado e atualizado no MB) será aquele que disparou a requisição (ele próprio no caso de um botão, ou o componente pai no caso de um support). Pode ser que passou a funcionar porque estava dando erro de validação em algum outro componente da tela e após a sua alteração esse componente não é processado e então o erro não ocorre mais.

Criado 9 de dezembro de 2009
Ultima resposta 12 de jul. de 2011
Respostas 12
Participantes 5