SelectOneMenus Aninhadas

Pessoal, estou com uma problema referente ao montar SelectOneMenus aninhadas com jsf.

O problema é o seguinte:

Ao clicar no primeiro select o mesmo preenche o segundo só que o ajax que trata o evento change da segunda combobox só funciona para o primeiro item, que coloquei um valor padrão default, então ele chama o listener somente quando clico em —Selecione a marca—. Segue uma parte do xhtml abaixo:

<h:outputLabel value="Tipo Equipamento:"/> <h:selectOneMenu id="tipo" value="#{inventarioBean.tipoEquipamento}"> <f:selectItems value="#{equipamentoBean.tipoEquipamentos}" var="item" itemLabel="#{item.nomeTipoEquipamento}" itemValue="#{item}"/> <f:converter converterId="tipoEquipamentoConverter"/> <f:ajax event="change" listener="#{inventarioBean.listaMarca}" render="marca"/> </h:selectOneMenu> <h:outputLabel value="Marca:" /> <h:selectOneMenu value="#{inventarioBean.marca}" id="marca"> <f:selectItem itemValue="" itemLabel="----Selecione a Marca----"/> <f:selectItems value="#{inventarioBean.marcas}" var="marca" itemLabel="#{marca.nomeMarca}" itemValue="#{marca}"/> <f:ajax event="valueChange" render="modelo" listener="#{inventarioBean.listaModelo}"/> </h:selectOneMenu> <h:outputLabel value="Modelo:"/> <h:selectOneMenu id="modelo" value="#{inventarioBean.modeloEquipamento}"> <f:selectItem itemValue="" itemLabel="----Selecione o Modelo----"/> <f:selectItems value="#{inventarioBean.modelos}" var="modelo" itemLabel="#{modelo.nomeModeloEquipamento}" itemValue="#{modelo}"/> </h:selectOneMenu>

Já tentei vária possibilidades, mas não consegui encontrar uma solução. Se alguém já passou por isso, poderia ajudar-me.

Obrigado pela atenção de todos.

Eu estou usando primefaces, e está funcionando aqui.
Segue o código para que possa vizualizar.
Tenta na tag f:ajax colocar actionListener.

Que erro está acontecendo?

[code]<h:outputText value=“Jornal” />
<h:selectOneMenu width=“30px”
value="#{vizualizarRecortesMB.estadoJornal}">
<f:selectItem itemLabel=“Selecione” itemValue=“Selecione”></f:selectItem>
<f:selectItems value="#{vizualizarRecortesMB.listaEstados}"
var=“estado” itemLabel="#{estado.uf}" itemValue="#{estado.uf}" />
<p:ajax actionListener="#{vizualizarRecortesMB.carregaArquivos}"
event=“change” update=“comboArquivos, msgs” />
</h:selectOneMenu>

				<h:outputText value="Arquivo" />
				<h:selectOneListbox id="comboArquivos"
					value="#{vizualizarRecortesMB.arquivo}">
					<f:selectItem itemLabel="Selecione" itemValue="Selecione"></f:selectItem>
					<f:selectItems value="#{vizualizarRecortesMB.listaArquivos}"
						var="arquivo" itemLabel="#{arquivo}" itemValue="#{arquivo}" />
				</h:selectOneListbox>

[/code]

Então , não acontece nenhum erro. Ele é executado só quando clico em —Selecione em Marca—.
O primeiro select que é do tipo de quipamento já tem suas opções carregadas quando a página é selecionada. Os outros 2 select
vem só com a opção default e a lista vazia do banco. Ao clicar no primeiro select o mesmo carrega dinamicamnete o segundo, mas o
listener do ajax só executado na primeira opção e não nas opções que foram carregadas dinamicamente.

Segue o xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
      xmlns:f="http://java.sun.com/jsf/core">
    <ui:composition template="/templates/principal.xhtml">
        <ui:define name="corpo">

            <p:panel id="panelPesquisaInventario" header="Pesquisa Inventário"
                     styleClass="panelPesquisaInventario">
                <h:panelGrid columns="2">
                    <h:outputLabel value="Pesquisa de Clientes:"/>
                    <p:autoComplete styleClass="inputComplete" 
                                    size="40"
                                    completeMethod="#{clienteBean.autoCompleteClientes}"
                                    var="cliente" 
                                    itemLabel="#{cliente.nomeCliente}"
                                    itemValue="#{cliente}">
                    </p:autoComplete>
                </h:panelGrid>
                <h:panelGrid columns="2" id="prod" rendered="#{inventarioBean.statusOneMenu}">
                    <h:outputLabel value="Tipo:"/>
                    <h:selectOneMenu>
                        <f:selectItems value="#{equipamentoBean.tipoEquipamentos}"
                                       var="item"
                                       itemLabel="#{item.nomeTipoEquipamento}"
                                       itemValue="#{item}"/>
                    </h:selectOneMenu>
                </h:panelGrid>
            </p:panel>

            <br />
            <p:separator style="width: 500px; text-align: left;"><h:outputLabel value="Cadastro de Inventário"/></p:separator>
            <h:panelGroup styleClass="panelCadastroInventario">
                <h:panelGrid columns="6" id="tabelaCadastroInventario">
                    <h:outputLabel value="Tipo Equipamento:"/>
                    <h:selectOneMenu id="tipo" value="#{inventarioBean.tipoEquipamento}">
                        <f:selectItems value="#{equipamentoBean.tipoEquipamentos}"
                                       var="item" 
                                       itemLabel="#{item.nomeTipoEquipamento}"
                                       itemValue="#{item}"/>
                        <f:converter converterId="tipoEquipamentoConverter"/>
                        <f:ajax event="change" listener="#{inventarioBean.listaMarca}" 
                                render="marca"/>
                    </h:selectOneMenu>
                    <h:outputLabel value="Marca:" />
                    <h:selectOneMenu value="#{inventarioBean.marca}" id="marca">
                        <f:selectItem itemValue="" itemLabel="----Selecione a Marca----"/>
                        <f:selectItems value="#{inventarioBean.marcas}"
                                       var="marca"
                                       itemLabel="#{marca.nomeMarca}"
                                       itemValue="#{marca}"/>
                        <f:ajax event="change" render="modelo"
                                listener="#{inventarioBean.listaModelo}"/>
                    </h:selectOneMenu>
                    <h:outputLabel value="Modelo:"/>
                    <h:selectOneMenu id="modelo" value="#{inventarioBean.modeloEquipamento}">
                        <f:selectItem itemValue="" itemLabel="----Selecione o Modelo----"/>
                        <f:selectItems value="#{inventarioBean.modelos}"
                                       var="modelo"
                                       itemLabel="#{modelo.nomeModeloEquipamento}"
                                       itemValue="#{modelo}"/>
                    </h:selectOneMenu>
                </h:panelGrid>
            </h:panelGroup>
            <h:panelGrid columns="4">
                <p:commandLink value="Adicionar IP Access-Point" ajax="true"/>
                
            </h:panelGrid>
        </ui:define>
    </ui:composition>
</html>

Segue o Managed Bean:

import dao.DAOGenerico;
import dao.ModeloEquipamentoDAO;
import dominio.Marca;
import dominio.ModeloEquipamento;
import dominio.TipoEquipamento;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.event.ValueChangeEvent;
import org.primefaces.event.SelectEvent;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Controller("inventarioBean")
@Scope("request")
@ManagedBean(name="inventarioBean")
@RequestScoped
public class InventarioBean implements Serializable{
    
    private boolean statusOneMenu = false;
    private boolean statusCadastroInventario = false;
    private boolean statusPanelAccessPoint = false;
    private String selectBox;
    
    private ModeloEquipamento modeloEquipamento = new ModeloEquipamento();
    private TipoEquipamento tipoEquipamento = new TipoEquipamento();
    private Marca marca = new Marca();
    
    @Resource
    private DAOGenerico<ModeloEquipamento, Integer> modeloEquipamentoDAO;
    
    @Resource
    private DAOGenerico<Marca, Integer> marcaDAO;
    
    private List<ModeloEquipamento> modelos;
    private List<Marca> marcas;

    public boolean getStatusOneMenu() {
        return statusOneMenu;
    }

    public void setStatusOneMenu(boolean statusOneMenu) {
        this.statusOneMenu = statusOneMenu;
    }

    public boolean getStatusCadastroInventario() {
        return statusCadastroInventario;
    }

    public void setStatusCadastroInventario(boolean statusCadastroInventario) {
        this.statusCadastroInventario = statusCadastroInventario;
    }

    public boolean getStatusPanelAccessPoint() {
        return statusPanelAccessPoint;
    }

    public void setStatusPanelAccessPoint(boolean statusPanelAccessPoint) {
        this.statusPanelAccessPoint = statusPanelAccessPoint;
    }

    public String getSelectBox() {
        return selectBox;
    }

    public void setSelectBox(String selectBox) {
        this.selectBox = selectBox;
    }

    public List<ModeloEquipamento> getModelos() {
        return modelos;
    }

    public void setModelos(List<ModeloEquipamento> modelos) {
        this.modelos = modelos;
    }

    public DAOGenerico<ModeloEquipamento, Integer> getModeloEquipamentoDAO() {
        return modeloEquipamentoDAO;
    }

    public DAOGenerico<Marca, Integer> getMarcaDAO() {
        return marcaDAO;
    }

    public void setMarcaDAO(DAOGenerico<Marca, Integer> marcaDAO) {
        this.marcaDAO = marcaDAO;
    }
    
    public void setModeloEquipamentoDAO(DAOGenerico<ModeloEquipamento, Integer> modeloDAO) {
        this.modeloEquipamentoDAO = modeloDAO;
    }

    public ModeloEquipamento getModeloEquipamento() {
        return modeloEquipamento;
    }

    public void setModeloEquipamento(ModeloEquipamento modeloEquipamento) {
        this.modeloEquipamento = modeloEquipamento;
    }

    public TipoEquipamento getTipoEquipamento() {
        return tipoEquipamento;
    }

    public void setTipoEquipamento(TipoEquipamento tipoEquipamento) {
        this.tipoEquipamento = tipoEquipamento;
    }

    public Marca getMarca() {
        return marca;
    }

    public void setMarca(Marca marca) {
        this.marca = marca;
    }

    public List<Marca> getMarcas() {
        return marcas;
    }

    public void setMarcas(List<Marca> marcas) {
        this.marcas = marcas;
    }
    
    public void handleEvent(SelectEvent event){
        System.out.println("Select Item");
        this.statusCadastroInventario = false;
        this.statusOneMenu = true;
    }
    
    public void selectOneEvent(ValueChangeEvent event){
        System.out.println("Select Item painel 1");
        this.statusPanelAccessPoint = true;
    }
    
    public void novoInventario(){
        System.out.println("tst");
        this.statusOneMenu = false;
        this.statusCadastroInventario = true;
    }
    
    public void listaMarca(){
        String query = "SELECT marca FROM ModeloEquipamento modelo"
                + " INNER JOIN modelo.idTipoEquipamento as tipo"
                + " INNER JOIN modelo.idMarcaEquipamento as marca"
                + " WHERE tipo.idTipoEquipamento = :tipoEquipamento"
                + " GROUP BY marca.nomeMarca";
        System.out.println(tipoEquipamento.getIdTipoEquipamento());
        Map<String, Object> params = new HashMap<String,Object>();
        params.put("tipoEquipamento", tipoEquipamento.getIdTipoEquipamento()); 
        marcas = marcaDAO.listPesqParam(query, params); 
    }
    
    public void listaModelo(){
        System.out.println("lista modelo");
        if(this.marca != null){
            String query = "SELECT modelo FROM ModeloEquipamento modelo"
                    + " INNER JOIN modelo.idTipoEquipamento as tipo"
                    + " INNER JOIN modelo.idMarcaEquipamento as marca"
                    + " WHERE marca.idMarca = :marca";
            System.out.println(query);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("marca", marca.getIdMarca());
            modelos = modeloEquipamentoDAO.listPesqParam(query, params);
        }
    }
}

Grato.

Tenta fazer assim:

Na tag ajax coloue assim:

<f:ajax event="change" listener="#{inventarioBean.listaMarca}" render="marca"/>
No método listarMarca faça isso:

public void listaMarca(AjaxBehaviorEvent event){ String query = "SELECT marca FROM ModeloEquipamento modelo" + " INNER JOIN modelo.idTipoEquipamento as tipo" + " INNER JOIN modelo.idMarcaEquipamento as marca" + " WHERE tipo.idTipoEquipamento = :tipoEquipamento" + " GROUP BY marca.nomeMarca"; System.out.println(tipoEquipamento.getIdTipoEquipamento()); Map<String, Object> params = new HashMap<String,Object>(); params.put("tipoEquipamento", tipoEquipamento.getIdTipoEquipamento()); marcas = marcaDAO.listPesqParam(query, params); }

Não esqueça de importar:

import javax.faces.event.AjaxBehaviorEvent;

No f:ajax não encontrei esse atributo actionListener. Ele só tem listener.
Mesmo assim eu declaro no método aquele parâmetro do ActionEvent ?

Eu tô usando JSF 2.0.

deixa listener e no método tenta colocar como parametro:

AjaxBehaviorEvent event

Eu editei o post do código de exemplo.

Tenta aí e vê se funciona.

Então, alterei o método, mas continuou o mesmo problema.

Oi Leo, bom dia!

Eu fiz um exemplo aqui e funcionou, o erro deve estar acontecendo em outro lugar.

Coloquei em anexo o projeto que criei para testar a atualização ajax.

Esse projeto é maven project, estou utilizando o jboss 6 como application server.

Abs,

Oi Carlos, bom dia!

No projeto que você mandou-me você utiliza só dois selects. Na aplicação que estamos desenvolvendo aqui na empresa,
eu vou ter 3 combobox. O primeiro funciona o ajax para todas as opções, mas o segundo select o ajax não funciona para
as opções carregadas dinâmicamente.

Será que tenho que dar submit na página para que ele passe a reconhecer as outras opções do segundo combobox.

Valeu!!!

Pessoal, consegui resolver o problema dos selects.

Foi necessário criar binding para os 2 últimos select e adicionar os items dinâmicamente no Bean.

Para aqueles que tiverem alguma dúvida é só seguir abaixo os códigos:

inventario.xhtml

       <h:outputLabel value="Tipo Equipamento:"/>
       <h:selectOneMenu id="tipo" value="#{inventarioBean.tipoEquipamento}">
                        <f:selectItem itemValue="" itemLabel="----Selecione o tipo----"/>
                        <f:selectItems value="#{equipamentoBean.tipoEquipamentos}"
                                       var="item" 
                                       itemLabel="#{item.nomeTipoEquipamento}"
                                       itemValue="#{item}"/>
                        <f:converter converterId="tipoEquipamentoConverter"/>
                        <f:ajax event="change" listener="#{inventarioBean.listaMarca}" 
                                render="marca"/>
                    </h:selectOneMenu>
                    <h:outputLabel value="Marca:" />
                    <h:selectOneMenu value="#{inventarioBean.marca}" id="marca"
                                     binding="#{inventarioBean.selectMarca}">
                        <f:converter converterId="marcaConverter"/>
                        <f:ajax event="change" render="modelo"
                                listener="#{inventarioBean.listaModelo}"/>
                    </h:selectOneMenu>
                    <h:outputLabel value="Modelo:"/>
                    <h:selectOneMenu id="modelo" value="#{inventarioBean.modeloEquipamento}"
                                     binding="#{inventarioBean.selectModelo}">
                   <f:converter converterId="modeloConverter"/>   
                   </h:selectOneMenu>

Bean:

   private HtmlSelectOneMenu selectMarca;
   private HtmlSelectOneMenu selectModelo;

    public HtmlSelectOneMenu getSelectMarca() {
        return selectMarca;
    }

    public void setSelectMarca(HtmlSelectOneMenu selectMarca) {
        this.selectMarca = selectMarca;
    }

    public HtmlSelectOneMenu getSelectModelo() {
        return selectModelo;
    }

    public void setSelectModelo(HtmlSelectOneMenu selectModelo) {
        this.selectModelo = selectModelo;
    }

     public void listaMarca(){
        selectMarca.getChildren().clear();
        System.out.println("lista marca");
        String query = "SELECT marca FROM ModeloEquipamento modelo"
                + " INNER JOIN modelo.idTipoEquipamento as tipo"
                + " INNER JOIN modelo.idMarcaEquipamento as marca"
                + " WHERE tipo.idTipoEquipamento = :tipoEquipamento"
                + " GROUP BY marca.nomeMarca";
        Map<String, Object> params = new HashMap<String,Object>();
        if(tipoEquipamento.getIdTipoEquipamento()!= null){
            params.put("tipoEquipamento", tipoEquipamento.getIdTipoEquipamento()); 
            marcas = marcaDAO.listPesqParam(query, params); 
            

            List<SelectItem> items = new ArrayList<SelectItem>();
            for(Marca m : marcas){
                SelectItem item = new SelectItem();
                item.setLabel(m.getNomeMarca());
                item.setValue(m);
                items.add(item);
                System.out.println(m.getNomeMarca());
            }
            UISelectItems uiSi = new UISelectItems();
            uiSi.setValue(items);
            selectMarca.getChildren().add(uiSi);
        }
    }
    
    public void listaModelo(){
        System.out.println("lista modelo");
        selectModelo.getChildren().clear();
        if(this.marca != null || this.marca.getIdMarca()!= null){
            String query = "SELECT modelo FROM ModeloEquipamento modelo"
                    + " INNER JOIN modelo.idTipoEquipamento as tipo"
                    + " INNER JOIN modelo.idMarcaEquipamento as marca"
                    + " WHERE marca.idMarca = :marca";
            System.out.println(query);
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("marca", marca.getIdMarca());
            modelos = modeloEquipamentoDAO.listPesqParam(query, params);
            List<SelectItem> items = new ArrayList<SelectItem>();
            for(ModeloEquipamento m : modelos){
                SelectItem item = new SelectItem();
                item.setLabel(m.getNomeModeloEquipamento());
                item.setValue(m);
                items.add(item);
                System.out.println(m.getNomeModeloEquipamento());
            }
            UISelectItems uiSi = new UISelectItems();
            uiSi.setValue(items);
            selectModelo.getChildren().add(uiSi);
        }
    }

Falou!!!