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!!!