Boa noite.
Tenho uma tela chamada CadastroTime nela tenho um p:commandButton que não está chamando o método grava da bean. Quando retiro um p:selectOneMenu da tela o botão chama o método ou se eu colocar immediate=true no botão ele chama também, só que ai ele não popula o objeto.
Já fiz vários testes mas não conseguir identificar o problema.
Alguém já passou por um problema como esse que possa ajudar?
Problemas com p:commandButton ao chamar metodo da Bean
12 Respostas
Você poderia postar o código para que possamos analisar melhor?
Ok.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:decorate template="/template/template.xhtml">
<ui:define name="centro">
<h:form id="primeiroForm">
<div align="center" style=" margin-top: 20px;" >
<h:panelGrid id="primeiroPanelGrid" columns="1">
<p:outputLabel for="nome" value="Nome do Time"></p:outputLabel>
<p:inputText id="nome" size="50" value="#{timeController.time.nomeTime}"></p:inputText>
<p:outputLabel for="jogador" value="Jogador"></p:outputLabel>
<p:selectOneMenu id="jogador" size="50" value="#{timeController.jogador}" >
<f:selectItem itemLabel="Selecione"/>
<f:selectItems value="#{timeController.buscarJogador()}" var="jogador" itemValue="jogador" itemLabel="#{jogador.nomeJogador}"/>
</p:selectOneMenu>
<p:commandButton id="gravarTime" value="Gravar Time" action="#{timeController.gravarTime()}" style="margin-top: 20px"/>
</h:panelGrid>
</div>
</h:form>
Se eu tirar o p:selectOneMenu o commandButton volta a chamar o método.
Desta forma que está ele só chama o método se eu colocar immediate="true", mas ai ele quebra o ciclo do ajax.
</ui:define>
</ui:decorate>
</html>
Você tem um Converter de Jogador registrado para que o selectOneMenu possar converter seus objetos quando for popular a combo e converter o item da combo em objecto quando você seleciona um item da lista? Já verificou se esta gerando alguma Exception quando você seleciona um item da combo? Verifique estes pontos.
Bom não tenho Converter de Jogador , e não lança nenhuma Exception. No log só aparece o select que ele faz pra carregar a lista para o selectOneMenu ai depois eu clico no botão e não acontece nada.
Setei na mão os dados de jogador no método da Controller e funcionol. Agora pela tela com o selectOneMenu não submete.
Tenta usar no itemValue do selectItems o valor jogador.id, deve ficar assim
itemValue="#{jogador.id}"
Fiz um teste com seu código e fiz duas alterações, vê se ajuda:
Ao inves de usar action usei actionListener, e continha um erro na declaração do commandButton em itemValue="jogador", onde o correto seria itemValue="#{jogador}" faz as alterações e ver se resolve o seu problema.
Bom tentei desta forma também colocando jogador.seq no itemValue mas continuou da mesma forma sem chamar o método.
Fiz essas alterações e continuou do mesmo jeito , não chama o método quando clicamos no botão.
Olá,
A correção conforme sugerida por @Cleidiano mas usando action mesmo:
<p:selectOneMenu id="jogador" size="50" value="#{timeController.jogador}" >
<f:selectItem itemLabel="Selecione"/>
<f:selectItems value="#{timeController.buscarJogador()}" var="jogador" itemValue="#{jogador}" itemLabel="#{jogador.nomeJogador}"/>
</p:selectOneMenu>
<p:commandButton id="gravarTime" value="Gravar Time" action="#{timeController.gravarTime()}" style="margin-top: 20px"/>
No backing bean TimeController você deve ter os métodos “Jogador getJogador()” e “void setJogador(Jogador umJogador)”.
Quando você seleciona um jogador desse dropdown então o conteúdo do itemValue (do f:selectItems) é gravado no value (do p:selectOneMenu), assim é lido/gravado uma instância/objeto de Jogador.
O seu método TimeController.gravarTime() deve usar o seu TimeController.jogador e gravá-lo onde você escolheu.
Só para tirar dúvida, o seu método TimeController.buscarJogador() retorna uma lista/conjunto de jogadores, correto ? Em caso afirmativo, use um nome mais evidente como “buscaJogadores” por exemplo.
Bom aqui está a Controller
package br.com.jefferson.Controller;
import java.util.List;
import javax.faces.bean.ManagedBean;
import br.com.jefferson.DAO.JogadorDao;
import br.com.jefferson.DAO.TimeDao;
import br.com.jefferson.Model.Jogador;
import br.com.jefferson.Model.Time;
@ManagedBean(name=“timeController”)
public class TimeController {
private Time time = new Time();
private TimeDao timeDao = new TimeDao();
private Jogador jogador = new Jogador();
private JogadorDao jogadorDao = new JogadorDao();
private List<Jogador> listaJogadores;
public void gravarTime() {
time.setJogador(this.jogador);
this.timeDao.gravarTime(time);
}
public List<Jogador> buscarJogadores() {
listaJogadores = jogadorDao.recuperarResultados();
return listaJogadores;
}
public Jogador getJogador() {
return jogador;
}
public void setJogador(Jogador jogador) {
this.jogador = jogador;
}
public Time getTime() {
return time;
}
public void setTime(Time time) {
this.time = time;
}
public List<Jogador> getListaJogadores() {
return listaJogadores;
}
public void setListaJogadores(List<Jogador> listaJogadores) {
this.listaJogadores = listaJogadores;
}
}
Percebi que se eu preencher apenas o inputText com o nome do jogador e deixar o selecOneMenu sem objeto selecionado, ele chama o método e grava . Agora quando eu escolho o objeto(jogador) no selectOneMenu ai ele não chama o método.
Olá,
Li a documentação e achei que aceitasse um objeto qualquer como itemValue, mas não.
@Cleidiano e @LeoRDS estão certos.
Aqui uma solução com converter: http://stackoverflow.com/questions/4635302/object-as-itemvalue-in-fselectitems
Outra solução é você utilizar um Integer ou Long por exemplo, Integer jogadorId com seu setter and getter e usá-lo no seu dropdown ao invés do objeto jogador, assim no método gravarTime você usa um DAO Jogador jogador = jogadorDAO.findById(jogadorId);
<p:selectOneMenu id="jogador" size="50" value="#{timeController.jogadorId}" >
<f:selectItem itemLabel="Selecione"/>
<f:selectItems value="#{timeController.buscarJogador()}" var="jogador" itemValue="#{jogador.id}" itemLabel="#{jogador.nomeJogador}"/>
</p:selectOneMenu>
<p:commandButton id="gravarTime" value="Gravar Time" action="#{timeController.gravarTime()}" style="margin-top: 20px"/>
Assim deve funcionar.
Galera, @Cleidiano @LeoRDS @cviniciusm, as informações de voces estão corretas.
Fiz da forma como o @cviniciusm informou criando um jogadorId e recuperando o jogador pelo.
Fiz também as mudanças que @Cleidiano @LeoRDS citado acima na tela e funcionou perfeitamente.
Muito obrigado pelas informações.