[RESOLVIDO] JSF 2.0 - Dropdown dependente

12 respostas
N

Caros,

Sua ajuda será muito apreciada :smiley:

Estou estudando JSF 2.0 com PrimeFaces 3.4 e estou tendo um problemão pra implementar uma lista dependente de outra lista.

Possuo uma classe para registrar viagens, previamente cadastrada, a qual possui 3 atributos: origem, destino e custo(e ID).

Meu problema é que tenho outra classe chamada “Planos”, na qual seria selecionado a origem, o destino deveria ser preenchido baseado na origem que acabei de selecionar, e quando o destino for selecionado, o custo vir automático.

Não estou conseguindo implementar tal funcionalidade. Alguém me ajuda, por favor?

Atualmente eu estou fazendo da seguinte forma:

Planos.xhtml

<h:outputLabel value="From"/>
                        <h:selectOneMenu value="#{planController.plan.cityFrom}">
                            <f:selectItem itemLabel="Select One" itemValue=""/>
                            <f:selectItems value="#{planController.listarCitiesFrom}"/>
                            <f:ajax render="cityTo" event="change"/>
                        </h:selectOneMenu>

                        <h:outputLabel value="To"/>
                        <h:selectOneMenu id="cityTo" value="#{planController.plan.cityTo}">
                            <f:selectItem itemLabel="Select One" itemValue=""/>
                            <f:selectItems value="#{planController.listarCitiesTo}"/>
                        </h:selectOneMenu>

                        <h:outputLabel for="days" value="Days"/>
                        <h:inputText id="days" value="#{planController.plan.days}"/>

                        <h:outputLabel for="reason" value="Reason"/>
                        <h:inputText id="reason" value="#{planController.plan.reason}">
                        </h:inputText>

                        <h:outputLabel for="hotelCost" value="Hotel(USD)"/>
                        <h:inputText id="hotelCost" value="#{planController.plan.hotelCost}">
                            <f:convertNumber maxFractionDigits="2" locale="pt-BR" />
                            <f:ajax event="keyup" render="travelCost"/>
                        </h:inputText>

                        <h:outputLabel for="ticketCost" value="Ticket(USD)"/>
                        <h:inputText id="ticketCost" value="#{planController.plan.ticketCost}">
                            <f:convertNumber maxFractionDigits="2" locale="pt-BR" />
                            <f:ajax event="keyup" render="travelCost"/>
                        </h:inputText>

Dois métodos do meu “MB” para listar os “destino e origem” - PlanController.java

public DataModel getListarCitiesTo() {
        List<Travel> listaTo = new TravelDaoImp().getTravelTo();
        listaCitiesTo = new ListDataModel(listaTo);
        return listaCitiesTo;
    }

    public DataModel getListarCitiesFrom() {
        List<Travel> listaFrom = new TravelDaoImp().getTravelFrom();
        listaCitiesTo = new ListDataModel(listaFrom);
        return listaCitiesTo;
    }

Meus métodos no “DAO”

public List<Travel> getTravelFrom() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        Projection projection = Projections.property("cityFrom");
        Criteria criteria = session.createCriteria(Travel.class);
        criteria.setProjection(projection);
        List lista = criteria.list();
        t.commit();
        return lista;
    }
    
    public List<Travel> getTravelTo() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        Projection projection = Projections.property("cityTo");
        Criteria criteria = session.createCriteria(Travel.class);
        criteria.setProjection(projection);
        List lista = criteria.list();
        t.commit();
        return lista;
    }

Qualquer sugestão para ajudar nos meus estudos será muito bem-vinda!

12 Respostas

L

Porque não coloca um outro ajax no cityTo para ao selecionar um preencher o custo.

N

Fala, Lelê.

é isso o que estou tentando. Mas minha dificuldade ssta sendo no backingbean. Você pode me ajudar em como posso fazer isso?

L

Me explica o que você quer fazer.
Ao selecionar uma lista você quer popular uma outra é isso ?

N

Fala, Lele!

Eu tenho um dialog aberto para fazer a inserção(ou modificação) - o dialog é o mesmo - e a ideia é que quando eu selecionar o destino, por ajax, busque no BD as origens cadastradas previamente em uma outra parte do sistema.
Esta “outra parte do sistema” eu faço cadastro apenas Destino - Origem - Preço da viagem

Meu dialog:

<p:dialog header="Gerencia de Plan" widgetVar="dialogGerPlan"  resizable="false" modal="true" showEffect="slide" width="500">

            <h:form id="form3">
                <center>
                    <h:outputText value="Incorrect username or password!" rendered="#{param.erro}" style="color: darkred"/>
                </center>
                <div>
                    <h:panelGrid id="infosPlan" columns="2" style="margin-bottom:10px">

                        <h:outputLabel value="Employee"/>
                        <h:selectOneMenu id="employee" value="#{planController.plan.employee}">  
                            <f:selectItem itemLabel="Select One" itemValue="" />
                            <f:selectItems value="#{planController.employees}"/>
                        </h:selectOneMenu> 

                        <h:outputLabel value="From"/>
                        <h:selectOneMenu value="#{planController.plan.cityFrom}">
                            <f:selectItem itemLabel="Select One" itemValue=""/>
                            <f:selectItems value="#{planController.listarCitiesFrom}"/>
                            <f:ajax render="cityTo" event="change"/>
                        </h:selectOneMenu>

                        <h:outputLabel value="To"/>
                        <h:selectOneMenu id="cityTo" value="#{planController.plan.cityTo}">
                            <f:selectItem itemLabel="Select One" itemValue=""/>
                            <f:selectItems value="#{planController.listarCitiesTo}"/>
                        </h:selectOneMenu>

                        <h:outputLabel value="Date"/>
                        <p:calendar value="#{planController.plan.date}" pattern="dd/MMM/yyy" required="true" requiredMessage="obrigatorio">
                        </p:calendar>


                        <h:outputLabel for="days" value="Days"/>
                        <h:inputText id="days" value="#{planController.plan.days}"/>

                        <h:outputLabel for="reason" value="Reason"/>
                        <h:inputText id="reason" value="#{planController.plan.reason}">
                        </h:inputText>

                        <h:outputLabel for="hotelCost" value="Hotel(USD)"/>
                        <h:inputText id="hotelCost" value="#{planController.plan.hotelCost}">
                            <f:convertNumber maxFractionDigits="2" locale="pt-BR" />
                            <f:ajax event="keyup" render="travelCost"/>
                        </h:inputText>



                        <h:outputLabel for="ticketCost" value="Ticket(USD)"/>
                        <h:inputText id="ticketCost" value="#{planController.plan.ticketCost}">
                            <f:convertNumber maxFractionDigits="2" locale="pt-BR" />
                            <f:ajax event="keyup" render="travelCost"/>
                        </h:inputText>

                        <br/>
                        &lt;h:outputLabel for="travelCost" value="Total(USD)"/&gt;
                        <br/>
                        
                        &lt;h:outputText id="travelCost" for="travelCost" value="#{planController.plan.ticketCost + planController.plan.hotelCost}"&gt;
                            &lt;f:convertNumber maxFractionDigits="2" locale="pt-BR" /&gt;
                        &lt;/h:outputText&gt;
                        &lt;h:inputHidden value="#{planController.plan.travelCost}"/&gt;
                        <br/>

                        &lt;p:commandButton update=":form2:tabela" oncomplete="dialogGerPlan.hide();" actionListener="#{planController.adicionarPlan}" value="Insert Plan"/&gt;
                        &lt;p:commandButton update=":form2:tabela" oncomplete="dialogGerPlan.hide();" actionListener="#{planController.alterarPlan}" value="Update Plan"/&gt;

                    &lt;/h:panelGrid&gt;

                &lt;/div&gt;    
            &lt;/h:form&gt;
        &lt;/p:dialog&gt;

Meus DataModels dentro do meu MB:

public DataModel getListarCitiesTo() {
        List&lt;Travel&gt; listaTo = new TravelDaoImp().getTravelTo();
        listaCitiesTo = new ListDataModel(listaTo);
        return listaCitiesTo;
    }

    public DataModel getListarCitiesFrom() {
        List&lt;Travel&gt; listaFrom = new TravelDaoImp().getTravelFrom();
        listaCitiesTo = new ListDataModel(listaFrom);
        return listaCitiesTo;
    }

Meu DAO:

public List&lt;Travel&gt; getTravelFrom() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        Projection projection = Projections.property("cityFrom");
        Criteria criteria = session.createCriteria(Travel.class);
        criteria.setProjection(projection);
        List lista = criteria.list();
        t.commit();
        return lista;
    }
    
    public List&lt;Travel&gt; getTravelTo() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction t = session.beginTransaction();
        Projection projection = Projections.property("cityTo");
        Criteria criteria = session.createCriteria(Travel.class);
        criteria.setProjection(projection);
        List lista = criteria.list();
        t.commit();
        return lista;
    }
L

Ainda não entendi muito bem.
Vou te dizer o que entendi.

Ao escolher um “cityFrom” você quer que popule uma lista de “cityTo” correto ?

Após aí que não entendi o que você quer fazer.

N

Isso, até aí você entendeu bem.

A ideia é que eu cadastre no sistema as origens para cada destino(Muitos para muitos, isso é uma outra tabela no BD). Por exemplo:
RJ -> SP
RJ -> PR
SP ->PR
SP -> RJ
etc

Agora eu quero preencher uma outra tabela, chamada PLAN com mais atributos, por exemplo: funcionario, origem, destino, data da viagem, custo etc.

O que eu não estou conseguindo fazer é nessa parte do cadastro da PLAN, quando eu seleciono a Origem, fazer com que somente os destinos cadastrados para a origem que eu selecionei apareçam. Por exemplo:
Seleciono Origem RJ, aí em CityTo só deveria aparecer SP e PR

Mas só estou conseguindo fazer com que apareça a lista cityFrom "completa", incluindo o RJ.

Não sei se fui claro :s

Obrigadão pela atenção!!

Abraços

L

Você verificou se está sendo chamado o método getListarCitiesTo() ?

Acho que você teria que fazer um actionListener ou uma action passando o atributo do select.

N

Fala, Lele!

Sim, está sendo chamado.

Do jeito que está minha aplicação, tudo funciona. Mas está errado, porque não estou chamando uma lista de CitiesTo baseado no que selecionei em CityFrom :frowning:

N

Pode me dar uma luz em como faço o actionListener passando o atributo?
Essa é a parte que realmente não sei implementar

L

Então, como é select é um valueChangeListener.
Na tela você coloca no select um valueChangeListener apontando para o método que vai ficar no managedBean

Por exemplo.

<h:selectOneMenu value="#{planController.plan.cityFrom}" valueChangeListener="#{planController.carregaCityTo}"> 
    <f:selectItem itemLabel="Select One" itemValue=""/>  
    <f:selectItems value="#{planController.listarCitiesFrom}"/>  
    <f:ajax render="cityTo" event="change"/>  
</h:selectOneMenu>

Depois no managedBean você cria assim

public void carregaCityTo(ValueChangeEvent evento) {
        String codigoSelect= evento.getNewValue().toString();
        //Após recuperar, chamar o método que recupera a lista e setar o objeto.
    }

Tenta ver se você consegue chegar no valueChangeListener

N

GRANDE lele!

Cara, não tenho palavras pra te agradecer!

Meu problema era o maldito “valueChangeListener” com o (ValueChangeEvent).

RESOLVIDO!!!

L

De nada.
Qualquer coisa estamos aí.
Boa sorte.

Criado 18 de janeiro de 2013
Ultima resposta 23 de jan. de 2013
Respostas 12
Participantes 2