[RESOLVIDO] - Problema com JSF + Primefaces + Datagrid + <p:commandButton>

24 respostas
P

Bom dia galera,

Estou com o seguinte problema,

Tenho um datagrid que renderiza minha lista de Artigos.

<p:dataGrid var="artigo" value="#{colecaoArtigos.listaArtigos}"
							columns="1" paginatorPosition="bottom" paginator="true" rows="3"
							emptyMessage="Nenhum artigo cadastrado."
							paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">

							<p:fieldset toggleable="true" toggleSpeed="500" legend="Assunto"
								styleClass="layoutArtigo">
								<h:form id="javaForm">
									<br />
									<h:outputText id="titulo" styleClass="tituloArtigo"
										value="#{artigo.titulo}" />
									<br />
									<br />
									<h:outputText styleClass="conteudoArtigo" escape="false"
										value="#{artigo.conteudo}" />
									<br />
									<br />
									<h:outputText styleClass="labelBold" value="Autor: " />
									<h:outputText styleClass="label" value="#{artigo.autor}" />
									<br />
									<h:outputText styleClass="labelBold"
										value="Data de Publicação: " />
									<h:outputText styleClass="label" value="#{artigo.dataCriacao}" />
									<br />
									<div align="right">
										<p:commandButton action="#{artigo.montaVisualizacao}"
											value="Saiba Mais..."  ajax="false" />
									</div>
								</h:form>
							</p:fieldset>

						</p:dataGrid>

Dentro da mesma tenho um commandButton que chama um método que monta a visualização da minha página:

public void montaVisualizacao(ActionEvent a) {

		montaArtigo();

		SessionProcessor.montarVisualizacaoArtigo(artigo);

		try {

					FacesContext.getCurrentInstance().getExternalContext()
						.redirect(Constantes.PAGE_ARTIGO);
			
		} catch (IOException e) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_ERROR,
									"Servidor Temporariamente Indisponível, tente novamente mais tarde.",
									"Contate o Suporte Técnico."));

		}

	}

Meu problema é que ele não está caindo no método.

Desde já agradeço a toda comunidade!

24 Respostas

J

cara métodos de action do button naum precisam do parâmetro ActionEvent, o método naum tem parâmetro

P

Olá amigo, inicialmente fiz seo o ActionEvent mesmo no meio dos teste acabei deixando, com ou sem não deu certo…

T

O commandButton não deveria estar apontado para seucontroller.montaVisualizacao ao invés de artigo.montaVisualizacao?

J

tenta chamar o seu método no actionListener ao invés de chamar no action!.

P

jlsoliveirajr , já tentei ele não cai no método, em relação ao colocar o método no meu controller acredito que não seja o problema, mas sim uma boa prática, mas como por enquanto não estou implementando a persistência, apenas fazendo as regras de negócio por enquanto deixo na bean.

J

Notei uma coisa no seu codigo postado.

<p:commandButton action="#{artigo.montaVisualizacao}" value="Saiba Mais..." ajax="false" />

o “artigo” é uma variavel que você declarou no dataGrid, que tem como referência a classe artigo, e não do seu MB e pelo que eu entendi, você passa para o dataGrid
uma lista vindo do seu MB(#{colecaoArtigos.listaArtigos}).

tenta colocar a mesma referência(colecaoArtigos) para chamar o método, ficando assim:

<p:commandButton action="#{colecaoArtigos.montaVisualizacao}" value="Saiba Mais..." ajax="false" />

P

jlsoliveirajr,

Continua sem cair no método, de ambos os modos:

<p:commandButton actionListener="#{colecaoArtigos.artigo.montaVisualizacao}" value="Saiba Mais..." ajax="false"/> <p:commandButton action="#{colecaoArtigos.artigo.montaVisualizacao}" value="Saiba Mais..." ajax="false"/>

não carrega o método, o que acontece é que minha página xhtml da um refresh quando clico no botão só isso…

G

Então, o que o jlsoliveirajr quis dizer é: Que o método montaVisualizacao esta no manager Bean e não no javaBean Artigo.

Você deve colocar assim: #{seuManagerBean.metodo} .

Espero que tenha ficado claro.

K

Experimenta colocar o GRID dentro do FORM (tira de dentro do field e colocar envolta do grid). E p método action como foi dito não recebe parâmetro e retorna uma string, (para teste retorne “” (VAZIO)).

P

kalindii, meu FORM está fora do Grid agora, continuo com o mesmo problema não é feita a chamada do método segue meu xhtml e meu fonte:

.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:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:p="http://primefaces.org/ui">

<ui:composition template="/WEB-INF/template/template.xhtml">

	<ui:define name="contentHead">

		<title>titulo pagina</title>

		<h:outputStylesheet library="css/web" name="artigoStyle.css" />

	</ui:define>

	<ui:define name="content">
		<div style="min-height: 850px;">
			<h:form id="form">
				<p:layout style="min-width:800px;min-height:600px;" id="layout"
					styleClass="contentStatic">
					<p:layoutUnit position="west" minSize="610"
						header="Últimas Notícias">
						<br />

						<p:dataGrid var="artigo" value="#{colecaoArtigos.listaArtigos}"
							columns="1" paginatorPosition="bottom" paginator="true" rows="3"
							emptyMessage="Nenhum artigo cadastrado."
							paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">

							<p:fieldset toggleable="true" toggleSpeed="500" legend="Assunto"
								styleClass="layoutArtigo">
								<br />
								<h:outputText styleClass="tituloArtigo" value="#{artigo.titulo}" />
								<br />
								<br />
								<h:outputText styleClass="conteudoArtigo" escape="false"
									value="#{artigo.conteudo}" />
								<br />
								<br />
								<h:outputText styleClass="labelBold" value="Autor: " />
								<h:outputText styleClass="label" value="#{artigo.autor}" />
								<br />
								<h:outputText styleClass="labelBold"
									value="Data de Publicação: " />
								<h:outputText styleClass="label" value="#{artigo.dataCriacao}" />
								<br />
								<div align="right">
									<p:commandButton action="#{artigoController.montaVisualizacao}"
										value="Saiba Mais..." ajax="false" />
								</div>
							</p:fieldset>

						</p:dataGrid>

					</p:layoutUnit>

					<p:layoutUnit position="center" styleClass="contentStatic"
						minSize="300">
						<h3 align="center">Área do Cliente</h3>

						<a href="meulink"> <p:graphicImage
								styleClass="boxLink" value="/resources/images/links/link1.jpg"
								alt="linkTrt" /></a>
					</p:layoutUnit>
				</p:layout>
			</h:form>
		</div>
		<hr />
		<br />
	</ui:define>

</ui:composition>

</html>

ArtigoController

package br.com.jamilcaleffi.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.FileUploadEvent;


@ManagedBean(name = "artigoController")
public class ArtigoController {
	
	private ArtigoBean artigo = new ArtigoBean();

	public ArtigoBean getArtigo() {
		return artigo;
	}

	public void setArtigo(ArtigoBean artigo) {
		this.artigo = artigo;
	}
	
	public void limpar() {

		artigo = new ArtigoBean();

	}

	public String montaVisualizacao() {

		montaArtigo();

		SessionProcessor.montarVisualizacaoArtigo(artigo);

		try {

			if (artigo.getImagem().equals(""))
				FacesContext.getCurrentInstance().getExternalContext()
						.redirect(Constantes.PAGE_ARTIGO);
			else
				FacesContext.getCurrentInstance().getExternalContext()
						.redirect(Constantes.PAGE_ARTIGO);
		} catch (IOException e) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_ERROR,
									Constantes.ERRO_SERVER
									,Constantes.ERRO_INFO_CONTATO));

		}
		return "";
	}

	public void montaPreVisualizacao(){

		montaArtigo();

		SessionProcessor.montarVisualizacaoArtigo(artigo);

		try {

			if (artigo.getImagem().equals(""))
				FacesContext.getCurrentInstance().getExternalContext()
						.redirect(Constantes.PRE_ARTIGO_SEM_IMAGEM);
			else
				FacesContext.getCurrentInstance().getExternalContext()
						.redirect(Constantes.PRE_ARTIGO);
		} catch (IOException e) {
			FacesContext
					.getCurrentInstance()
					.addMessage(
							null,
							new FacesMessage(
									FacesMessage.SEVERITY_ERROR,
									Constantes.ERRO_SERVER
									,Constantes.ERRO_INFO_CONTATO));

		}
	}

	public void montaArtigo() {

		System.out.println("--> Método que monta a bean do artigo.");

		Date date = new Date();
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");

		artigo.setDataCriacao(simpleDateFormat.format(date));

		if (artigo.getImagem() == null)
			artigo.setImagem("");

		System.out.println("Fim do Método <---");

	}


}
K

Só para mim entender.
Você já fez algum teste pra ver se ele realmente esta encontrando esse backingBean controller?
Algo do tipo..

<div align="right">  
 #{artigoController.teste} //(ou .getTeste  qual que passa)
 <p:commandButton action="#{artigoController.montaVisualizacao}" value="Saiba Mais..." ajax="false" />  
</div>
public String getTeste() {  
 return "Teste";
}

Se por acaso, esteja realmente chamando, o console esta dando algum erro? Se tiver seria interessante você postar pra ajuda?

P

kalindii , sim, sim, fiz o teste.

Vou postar aki o exemplo de teste que fiz para vocês entenderem:

meu button:
<p:commandButton action="#{artigoController.teste}"
										value="Saiba Mais..."/>
método teste
public String teste(){
		
		System.out.println("teste");
		
		return "";
	}

Se eu colocar este método fora do meu datagrid ele funciona normalmente.

Mas interessante é que este mesmo método fora do datagrid ele não funciona, sequer a chamada do método.

Mais uma observação é que ao clicar no botão é dado um refresh na página e por conseguinte instancia novamente a página.

Exemplo da minha pilha:

--------------------------------------------------

teste
17/07/2012 15:34:01 org.apache.myfaces.config.annotation.Tomcat7AnnotationLifecycleProvider newInstance
INFO: Creating instance of br.com.jamilcaleffi.view.managed.artigo.ColecaoArtigos

--------------------------------------------------

O teste printado no meu console é referente ao button fora do datagrid.

e o segundo é o meu método chamado dentro do datagrid.

________________________________________________________

Agora falando a respeito do que eu quero fazer.

Tenho um sistema em que crio um artigo, edito, listo entre outras funções gerais do sistema... Este artigo é postado na minha index e é listado dentro de um datagrid, como mostrado acima.

A listagem está funcionando perfeitamente, o que ocorre é que através do button carrega meu método que é responsável por montar a página de exibição do meu artigo. Este método está funcionando porque dentro do modo de edição que eu programei eu monto uma pré visualização que monta meu artigo e mosta essa prévia na tela.
________________________________________________________

Mais ou menos isso, fazendo muitos teste aqui mais até agora nada, rsrs

K

Fiquei confusa quanto a isto…

Não entendi se vc confundiu, ou se o método ora funciona fora ora não.

Quanto a refresh é pq o ajax do seus commandButton esta setado como false, ou seja a requisição do botao não esta sendo feita via ajax. Para fazer por ajax, ou vc set para ajax=“true”.

Agora deixa eu ver se entendi, vc quer listar os arquivos que vc possui dentro de um dataGrid (que com vc disse já esta funcionando), e quando clicar no botão poder visualizá-los, seria isso?

P

rsrs, me confundi msm…

O button dentro do datagrid não funciona. E fora do datagrid funciona.

Sim, ao clicar no meu button o intuito é pegar os atributos daquele fieldset q está dentro do datagrid e abrir uma página nova contendo aquelas informações, claro que se tiver outra sugestão de como faze-lo eu agradeço. Tentei até fazer isso por javascript mas o primefaces concatena e tal as ids ai estava tentando por java mesmo…

P

Este é um projeto pessoal, hoje trabalho com java mas para o HSBC onde utilizo metodologias diferentes e tal, o “bendito” Execution Services, uma modificação do Spring e tal. Porem gosto muito de utilizar o primefaces, mas ainda dou umas esbarradas legais nele… kkkk

K

Nesse caso você pode usar o DataTable então ao invez do DataGrid, se é pra listagem tbm. Ele funciona tranquilo com commandButton.

P

Nada de funcionar, com datalist também não chamou meu método.

F

No show case ele usa um <p:column> ao inves de <p:fieldset>, tenta alterar isso pra ver se resolve…

http://www.primefaces.org/showcase/ui/datagrid.jsf

P

ffontoura, eu coloquei o o fieldset por questão pessoal mesmo, porque o que o datagrid faz é listar todo meu ArrayList e renderizar as informações que eu trago dentro deste fieldset

P

Consegui entrar no método utilizando <p:remoteCommand>

Ficou assim:

<p:commandButton type="button" onclick="carrega()" id="btnLoad" value="Saiba Mais..." />

e meu remoteCommand:

<p:remoteCommand name="carrega" actionListener="#{artigoController.montaVisualizacao}"/>

Porém chamando pelo remoteCommand ele não carrega os valores da linha que eu selecionei e acionei meu button…

Pelo menos o método carregou, agora tentando pegar os valores, se alguém tiver uma sugestão, fico grato kkk

P

coloquei um <f:setPropertyActionListener target="#{artigoController.artigo}" value="#{artigo}" />

Mas minha página retorna em branco e em debug meu parametros estão nulls

M

Isso me parecer ser um problema de escopo de sessão, inclusive já tive problemas semelhantes. Tem que tomar cuidado quando inserir componentes com action (commandButton, commandLink e derivados) dentro de componentes que trabalham com coleções (dataGrid, ring, dataTable, ui:repeat) porque ao fazer a requisição a lista já está vazia.

Se você colocar em sessionScoped deve funcionar, ou mude seu método do get para montar novamente a lista se ela for nula.

Segue dois links que explicam mais profundamente:


P

Exatamente Marcos,

Acabei de resolver aqui mas não da forma mais elegante podemos dizer, eu consegui chamar minha Action por remotecommand mas não conseguia passar meu parametro.

O que fiz foi fazer uma bela de uma gambiarra aqui.

O que fiz foi trazer a ID do meu artigo escondida dentro do meu link… ficou mais ou menos assim:

<a href="minhapagina...." rel="#{artigo.caminhoArtigo}" onclick="carregaPagina(this)" >

Jogo meu rel dentro do meu value de um input hidden e mando por get mesmo para minha outra página e la faço o tratamento etc…

Bom meu problema foi resolvido mas não da forma mais elegante, mas vou dar uma boa olhada nos links que me passou mas acredito que o maior problema seja esse mesmo que você falou.

Obrigado a todos que ajudaram aqui.

M

Isso me parece ser um problema de escopo de sessão, inclusive já tive problemas semelhantes. Tem que tomar cuidado quando inserir componentes com action (commandButton, commandLink e derivados) dentro de componentes que trabalham com coleções (dataGrid, ring, dataTable, ui:repeat) porque ao fazer a requisição a lista já está vazia.

Se você colocar em sessionScoped deve funcionar, ou mude seu método do get para montar novamente a lista se ela for nula.

Segue dois links que explicam mais profundamente:


Criado 14 de julho de 2012
Ultima resposta 23 de jul. de 2012
Respostas 24
Participantes 8