TransWikia.com

SelectOneMenu não é carregado ao selecinar objeto para edição

Stack Overflow em Português Asked on December 9, 2021

Tenho um componente SelectOneMenu (Primefaces) de cidades, que é carregado de acordo com o estado selecionado.

Meu componente está com seguinte comportamento, logo após salvar o objeto e em seguida seleciona-lo no DataTable através de um commandLink para edição, o componente é carregado com a cidade normalmente, mas se eu sair da página e retornar para depois fazer a edição, esse componente não vem carregado.

Já fiz o degug e o valor da cidade vem preenchido, mas não sei porque não é apresentado no componente. Se alguém puder me ajudar, já tentei de tudo.

Classe Endereco com os mapeamentos

@Entity
@Table(name="TENDERECO", schema="SGCADM")
public class Endereco implements Serializable{
private Cidade cidade;
    private Estado estado;
    private Pessoa pessoa;

@JoinColumn(name = "CODCID", referencedColumnName = "CODCID")
        @ForeignKey(name = "fk_endereco_cidade")    
        public Cidade getCidade() {
            if (cidade == null) {
                cidade = new Cidade();
            }
            return cidade;
        }

        public void setCidade(Cidade cidade) {
            this.cidade = cidade;
        }

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "CODESTA", referencedColumnName = "CODESTA")
        @ForeignKey(name = "fk_endereco_estado")    
        public Estado getEstado() {
            if (estado == null) {
                estado = new Estado();
            }
            return estado;
        }
        public void setEstado(Estado estado) {
            this.estado = estado;
        }   

        @OneToOne(targetEntity = Pessoa.class, fetch=FetchType.LAZY)    
        @JoinColumn(name = "CODPES", referencedColumnName = "CODPES")
        @ForeignKey(name = "fk_endereco_pessoa")
        public Pessoa getPessoa() {
            return pessoa;
        }
        public void setPessoa(Pessoa pessoa) {
            this.pessoa = pessoa;
        }

Bean com scopo @viewScoped

@ManagedBean(name="funcionarioBean")
@ViewScoped
public class FuncionarioBean implements Serializable{

    @EJB private FuncionarioBO funcionarioBO;

    @EJB private CidadeBO cidadeBO;

    @EJB private EstadoBO estadoBO;     

    @PostConstruct
    public void init(){
        this.listCargo = cargoBO.buscarCargos();
        this.listEstado = estadoBO.buscarEstados(); 
        this.listGerentesSupervisores = funcionarioBO.listaGerentesSupervisores();
        listarFuncionarios();
    }

    public void populaCidades(AjaxBehaviorEvent event) throws TransactionalException {
        listCidadePorEstado = cidadeBO.buscarCidadesPorEstado(getFuncionario().getEndereco().getEstado().getCodigoEstado());
    }

    public void salvar() throws PersistenceException, ParseException {
        try {
            funcionario.setDataCadastro(dataAtual);
            funcionario.setTipoPessoa(TipoPessoaEnum.FISICA);
            funcionario.setDataNascimento(formata.parse(DateUtils.formataData(funcionario.getDataNascimento())));
            funcionario.getEndereco().setDataCadastro(dataAtual);
            funcionario.getEndereco().setPessoa(funcionario);
            funcionarioBO.salvarFuncionario(funcionario);
            FacesUtil.info("Funcionário foi salvo com sucesso ! ");
            listarFuncionarios();
            limpar();
        } catch (TransactionalException e) {
            e.printStackTrace();
            logger.error("Não foi possível salvar Funcionario ! " + e.getMessage());
            FacesUtil.error(FacesMessage.SEVERITY_ERROR, "Não foi possível salvar funcionário ! ", e.getMessage());
        }
    }

    public void editar(){
        funcionario = funcionarioBO.find(funcionario.getCodigoFuncionario());
        disable = false;
        btnNew = true;
        btnSave = false;
        btnCancel = false;
    }


}

Implementação do Método buscaCidadePorEstado

public List<Cidade> buscarCidadesPorEstado(Long codigoEstado) throws TransactionalException{
         Criteria cri = getSession().createCriteria(Cidade.class)
                 .add(Restrictions.eq("estado.codigoEstado", codigoEstado));         
        return cri.list();

    }

selectOneMenu Estado e Cidade junto com commandLink que busca
o objeto selecionado do meu dataTable:

<p:selectOneMenu id="Selest" value="#{funcionarioBean.funcionario.endereco.estado.codigoEstado}" required="true" requiredMessage="O campo ESTADO é obrigatório !" style="width:175px; margin-left: 5px; font-weight:bold;" disabled="#{funcionarioBean.disable}">
  <f:selectItem itemLabel="" itemValue="" />
  <f:selectItems value="#{funcionarioBean.listEstado}" var="item" itemLabel="#{item.descricao}" itemValue="#{item.codigoEstado}" />
  <f:ajax event="change" render="Selcid" listener="#{funcionarioBean.populaCidades}" />
</p:selectOneMenu>

<p:selectOneMenu id="Selcid" value="#{funcionarioBean.funcionario.endereco.cidade.codigoCidade}" style="width:175px; margin-left: 5px;font-weight:bold;" required="true" requiredMessage="O campo CIDADE é obrigatório !" disabled="#{funcionarioBean.disable}">
  <f:selectItem itemLabel="" itemValue="" />
  <f:selectItems value="#{funcionarioBean.listCidadePorEstado}" var="cid" itemLabel="#{cid.descricao}" itemValue="#{cid.codigoCidade}" />
</p:selectOneMenu>



<p:column id="edit" width="9%" style="text-align:center">
  <p:commandLink action="#{funcionarioBean.editar}" ajax="false" update=":form:view">
    <p:graphicImage value="/resources/img/icon/Edit16x16.png" />
    <f:setPropertyActionListener value="#{obj}" target="#{funcionarioBean.funcionario}" />
  </p:commandLink>
</p:column>

2 Answers

Chame populaCidades no editar():

 public void editar(){
        funcionario = funcionarioBO.find(funcionario.getCodigoFuncionario());
        populaCidades(null);
        disable = false;
        btnNew = true;
        btnSave = false;
        btnCancel = false;
    }

Quando você entra a primeira vez na página, para criar o funcionário você não espera que a lista de cidades esteja preenchida. Ao escolher um estado vai disparar o evento e popular a lista de ciades. OK. Daí quando você volta para a listagem e seleciona o mesmo funcionário para edição, como o escopo do managed bean é view, funcionarioBean ainda está com listCidadePorEstado preenchido.

Agora, se você sai da página, isto é do escopo, quando volta para a página e escolhe o funcionário para edição a lista de cidades não está preenchida e não ocorreu nenhum evento que a popule.

Answered by mari on December 9, 2021

Não precisa colocar o update="Selcid" no seu combo de estado?

 <f:ajax event="change" render="Selcid" update="Selcid" listener="#{funcionarioBean.populaCidades}" />

Answered by Renato Guedes on December 9, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP