Problemas com p:commandButton ao chamar metodo da Bean

12 respostas Resolvido
java
J

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?

12 Respostas

C

Você poderia postar o código para que possamos analisar melhor?

J

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  chama o método se eu colocar immediate="true", mas ai ele quebra o ciclo do ajax.
         </ui:define>
  </ui:decorate>
</html>
C

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.

J

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.

L

Tenta usar no itemValue do selectItems o valor jogador.id, deve ficar assim

itemValue="#{jogador.id}"

C

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.

J

Bom tentei desta forma também colocando jogador.seq no itemValue mas continuou da mesma forma sem chamar o método.

J

Fiz essas alterações e continuou do mesmo jeito , não chama o método quando clicamos no botão.

C

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.

J

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.

C
Solucao aceita

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.

J

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.

Criado 27 de outubro de 2016
Ultima resposta 29 de out. de 2016
Respostas 12
Participantes 4