[Resolvido] Editar objeto com Dialog (Primefaces)

Bom dia pessoal.

Iniciei a pouco tempo meus estudos sobre jsf e primefaces e estou com um problema que não estou conseguindo solucionar, editar um objeto em um dialog, basicamente, é carrega-lo no dialog.
Estou usando um data table com selection single mode. O objeto e clicar em uma das linhas (objeto) e, em seguida, clicar no botão editar e, então, o dialog carregaria uma janela para a edição das informações deste objeto, acontece que o dialog não carrega este objeto.

Montei um pequeno exemplo para mostrar meu problema mais facilmente,

Abaixo, minha class teste.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="/_template.xhtml">

	<ui:define name="corpo">
		
		<h:form id="form">
		
			<p:tabView>
			
				<p:tab title="teste">
				
					<fieldset>
					
						<legend>Tabela Teste</legend>
						
						<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" 
							selection="#{testeBean.teste}" rowKey="#{teste.id}"  >
						
							<p:column id="descricao" filterBy="#{teste.descricao}" >
								<h:outputText value="#{teste.descricao}" />
							</p:column>						
						
						</p:dataTable>
						
						<p:commandButton id="novo" value="Novo" onclick="novoDialogo.show()" type="button" />
						<p:commandButton id="editar" value="Editar" onclick="novoDialogoEdit.show()" type="button" >
							<f:ajax render="modalTesteEditar" execute="@form" />
						</p:commandButton>
						
						<p:dialog id="modalTesteNovo" header="Teste Modal" widgetVar="novoDialogo" modal="true" dynamic="true" >
							<h:outputText value="Descrição: " />
							<p:inputText value="#{testeBean.teste.descricao}" />
							
							<p:commandButton value="Salvar" action="#{testeBean.grava}" oncomplete="novoDialogo.hide()" onclick="teste" >
								<f:ajax execute="@this" render="@form" />
							</p:commandButton>
						</p:dialog>		
						
						<p:dialog id="modalTesteEditar" header="Teste Modal Edit" widgetVar="novoDialogoEdit" modal="true" dynamic="true" >
							
							<h:outputText value="#{testeSelecionado.descricao}" />
							
						</p:dialog>										
																					
					</fieldset>
				
				</p:tab>
			
			</p:tabView>
		
		</h:form>
		
	</ui:define>

</ui:composition>

</html>

Aqui esta meu ManagedBean:

package br.com.enterprisestoq.bean;

import java.io.Serializable;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import br.com.enterprisestoq.dao.DAO;
import br.com.enterprisestoq.modelos.Teste;

@ManagedBean
@ViewScoped
public class TesteBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Teste teste = new Teste();
	private Teste testeSelecionado;
	private List<Teste> testes;
	
	public String grava(){
		DAO<Teste> dao = new DAO<Teste>(Teste.class);
		dao.adiciona(teste);
		this.teste = new Teste();
		return "teste";
	}
		
	public Teste getTeste() {
		return teste;
	}

	public void setTeste(Teste teste) {
		this.teste = teste;
	}

	public List<Teste> getTestes() {
		DAO<Teste> dao = new DAO<Teste>(Teste.class);
		this.testes = dao.listaTodos();
		return this.testes;
	}

	public void setTestes(List<Teste> testes) {
		this.testes = testes;
	}

	public Teste getTesteSelecionado() {
		return testeSelecionado;
	}

	public void setTesteSelecionado(Teste testeSelecionado) {
		this.testeSelecionado = testeSelecionado;
	}

}

O que estou fazendo de errado? Ja tentei seguir o exemplo dos cases do site do primefaces, porém o resultado é o mesmo.

Muito obrigado.

Bom dia!

Cara, em qual dos commandButton esta dando errado? Nos dois?
Ele exibe o Dialog, nos dois casos, mas sem valor?

[]'s

[quote=ThEDiegO]Bom dia pessoal.

Iniciei a pouco tempo meus estudos sobre jsf e primefaces e estou com um problema que não estou conseguindo solucionar, editar um objeto em um dialog, basicamente, é carrega-lo no dialog.
Estou usando um data table com selection single mode. O objeto e clicar em uma das linhas (objeto) e, em seguida, clicar no botão editar e, então, o dialog carregaria uma janela para a edição das informações deste objeto, acontece que o dialog não carrega este objeto.

Montei um pequeno exemplo para mostrar meu problema mais facilmente,

Abaixo, minha class teste.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="/_template.xhtml">

	<ui:define name="corpo">
		
		<h:form id="form">
		
			<p:tabView>
			
				<p:tab title="teste">
				
					<fieldset>
					
						<legend>Tabela Teste</legend>
						
						<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" 
							selection="#{testeBean.teste}" rowKey="#{teste.id}"  >
						
							<p:column id="descricao" filterBy="#{teste.descricao}" >
								<h:outputText value="#{teste.descricao}" />
							</p:column>						
						
						</p:dataTable>
						
						<p:commandButton id="novo" value="Novo" onclick="novoDialogo.show()" type="button" />
						<p:commandButton id="editar" value="Editar" onclick="novoDialogoEdit.show()" type="button" >
							<f:ajax render="modalTesteEditar" execute="@form" />
						</p:commandButton>
						
						<p:dialog id="modalTesteNovo" header="Teste Modal" widgetVar="novoDialogo" modal="true" dynamic="true" >
							<h:outputText value="Descrição: " />
							<p:inputText value="#{testeBean.teste.descricao}" />
							
							<p:commandButton value="Salvar" action="#{testeBean.grava}" oncomplete="novoDialogo.hide()" onclick="teste" >
								<f:ajax execute="@this" render="@form" />
							</p:commandButton>
						</p:dialog>		
						
						<p:dialog id="modalTesteEditar" header="Teste Modal Edit" widgetVar="novoDialogoEdit" modal="true" dynamic="true" >
							
							<h:outputText value="#{testeSelecionado.descricao}" />
							
						</p:dialog>										
																					
					</fieldset>
				
				</p:tab>
			
			</p:tabView>
		
		</h:form>
		
	</ui:define>

</ui:composition>

</html>

Aqui esta meu ManagedBean:

package br.com.enterprisestoq.bean;

import java.io.Serializable;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import br.com.enterprisestoq.dao.DAO;
import br.com.enterprisestoq.modelos.Teste;

@ManagedBean
@ViewScoped
public class TesteBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Teste teste = new Teste();
	private Teste testeSelecionado;
	private List<Teste> testes;
	
	public String grava(){
		DAO<Teste> dao = new DAO<Teste>(Teste.class);
		dao.adiciona(teste);
		this.teste = new Teste();
		return "teste";
	}
		
	public Teste getTeste() {
		return teste;
	}

	public void setTeste(Teste teste) {
		this.teste = teste;
	}

	public List<Teste> getTestes() {
		DAO<Teste> dao = new DAO<Teste>(Teste.class);
		this.testes = dao.listaTodos();
		return this.testes;
	}

	public void setTestes(List<Teste> testes) {
		this.testes = testes;
	}

	public Teste getTesteSelecionado() {
		return testeSelecionado;
	}

	public void setTesteSelecionado(Teste testeSelecionado) {
		this.testeSelecionado = testeSelecionado;
	}

}

O que estou fazendo de errado? Ja tentei seguir o exemplo dos cases do site do primefaces, porém o resultado é o mesmo.

Muito obrigado.[/quote]

Cara, vc precisa passar o Objeto para o Dialog exibir com o:

<f:setPropertyActionListener target="#{eventoBean.eventoSelecionado}" value="#{evento}"/>

Ficaria dessa forma:

<p:commandButton icon="ui-icon-circle-check" ajax="true" update="formEvento" immediate="true" oncomplete="janela.show()"> <f:setPropertyActionListener target="#{eventoBean.eventoSelecionado}" value="#{evento}"/> </p:commandButton>

Olá!
Rapaz, ele da esse problema no botão de edição. Eu tendo selecionar um linha no data table com o selection="#{testeBean.testeSelecioado}".

Apenas corrigindo, o meu selection no data table aponta para testeSelecioado, e não teste como coloquei no exemplo. Dessa forma, ao meu ver, ele deveria setar o objeto testeSelecioado no Bean e o dialogo deveria renderizar junto com ele, ja que estou fazendo chamadas direto deste objeto:

                        <p:dialog id="modalTesteEditar" header="Teste Modal Edit" widgetVar="novoDialogoEdit" modal="true" dynamic="true" >  
                              
                            <h:outputText value="#{testeSelecionado.descricao}" />  
                              
                        </p:dialog> 

Meu problema é basicamente em fazer essa ação, carregar o objeto selecionado atravez do botão id=“editar”, alterar esse objeto no dialog e salvar no banco. Mas nem carrega-lo no dialog estou conseguindo fazer.

Obrigado

[quote=Diego Adriano]Cara, vc precisa passar o Objeto para o Dialog exibir com o:

<f:setPropertyActionListener target="#{eventoBean.eventoSelecionado}" value="#{evento}"/>

Ficaria dessa forma:

<p:commandButton icon="ui-icon-circle-check" ajax="true" update="formEvento" immediate="true" oncomplete="janela.show()"> <f:setPropertyActionListener target="#{eventoBean.eventoSelecionado}" value="#{evento}"/> </p:commandButton>
[/quote]

Eu achei que o selection do data table ja fizesse isso, mas vou realizar um teste aqui.

Obrigado

Então cara, se vc deixa o Selection ativo pq vc coloca um botão lá ??? É meio sem logica …
Mas testa ai …

[quote=Diego Adriano]Então cara, se vc deixa o Selection ativo pq vc coloca um botão lá ??? É meio sem logica …
Mas testa ai …[/quote]

Bom, fiz isso com base no exemplo do primefaces. Pelo o que entendi la, o selection irá setar o objeto no bean com a linha que eu selecionar e, depois, apenas clicaria no botão editar e ele carregaria este objeto dentro do dialog “editar”. Meu raciocinio está errado?

Quando vc faz isso:

<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" selection="#{testeBean.teste}" rowKey="#{teste.id}" >
o datatable faz a seleção do atributo automático, não precisa usar o setPropertyActionListener, e sim preencher o atributo selection da tag com o atributo do ManagedBean como vc fez acima.

e nesse trecho ficaria assim:

[code]<p:dialog id=“modalTesteEditar” header=“Teste Modal Edit” widgetVar=“novoDialogoEdit” modal=“true” dynamic=“true” >

<h:outputText value="#{testeBean.teste.descricao}" />    

</p:dialog>[/code]

E também precisa retirar a linha do ajax:

<p:commandButton id="novo" value="Novo" onclick="novoDialogo.show()" type="button" /> <p:commandButton id="editar" value="Editar" onclick="novoDialogoEdit.show()" type="button" > <f:ajax render="modalTesteEditar" execute="@form" /> //RETIRAR </p:commandButton>

Foi o que exatamente o que eu disse a ele, se vai usar o Selection automático não precisa do botão, mas se ele quer fazer com o botão então precisa do setproperty …

Bom vamos lá.

Fiz algumas alterações mas o resultado esta sendo o mesmo.
Como citei anteriormente, criei uma variavel (testeSelecionado) exclusivamente para receber o objeto selecionado no data table:

						<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" 
							selection="#{testeBean.testeSelecionado}" rowKey="#{teste.id}"  >
						
							<p:column id="descricao" filterBy="#{teste.descricao}" >
								<h:outputText value="#{teste.descricao}" />
							</p:column>						
						
						</p:dataTable>

Depois eu clico no botão “editar” e nele eu uso um <p:outputtext> para exibir o campo descrição do objeto testeSelecionado que, teoricamente, deveria ter sido carregado no momento em que eu selecionei a linha no data table.

No TesteBean eu tenho uma variável “testeSelecionado” e não estou instânciando ela, ao meu ver, ela será instanciada pelo data table no momento do selection, mas de qualquer, mesmo eu instânciando ela, o resultado é o mesmo.

Hoje ficando doido com isso!! Não aparece nenhum erro no console, funciona tudo normal.

Seu raciocínio está certo, e mesmo usando o botão editar que exibe um dialog não precisa setar o objeto com setPropertyActionListener.
Seu selection não precisa ficar assim: selection="#{testeBean.testeSelecionado}" já que é feito automático com o selection="#{testeBean.teste}".

e altere pra isso:

[code]<p:dialog id=“modalTesteEditar” header=“Teste Modal Edit” widgetVar=“novoDialogoEdit” modal=“true” dynamic=“true” >

<h:outputText value="#{testeBean.teste.descricao}" />      

</p:dialog> [/code]

Mas se quiser complicar com um property que marca o selecionado (testeSelecionado), tudo bem.

[quote=nana_ps]Seu raciocínio está certo, e mesmo usando o botão editar que exibe um dialog não precisa setar o objeto com setPropertyActionListener.
Seu selection não precisa ficar assim: selection="#{testeBean.testeSelecionado}" já que é feito automático com o selection="#{testeBean.teste}".

e altere pra isso:

[code]<p:dialog id=“modalTesteEditar” header=“Teste Modal Edit” widgetVar=“novoDialogoEdit” modal=“true” dynamic=“true” >

<h:outputText value="#{testeBean.teste.descricao}" />      

</p:dialog> [/code]

Mas se quiser complicar com um property que marca o selecionado (testeSelecionado), tudo bem.[/quote]

Então, eu usei o testeSelecionado numa tentativa frustada de fazer funcionar, mesmo setando diretamente para “teste”, o resultado é o mesmo.

Atualizando meus códigos:

						<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" 
							selection="#{testeBean.teste}" rowKey="#{teste.id}"  >
						
							<p:column id="descricao" filterBy="#{teste.descricao}" >
								<h:outputText value="#{teste.descricao}" />
							</p:column>						
						
						</p:dataTable>

e meu dialog:

						<p:dialog id="modalTesteEditar" header="Teste Modal Edit" widgetVar="novoDialogoEdit" modal="true" dynamic="true" >
							<h:outputText value="Descriçao do teste selecionado:" />
							<h:outputText value="#{testeBean.teste.descricao}" />
							
						</p:dialog>		

Vc retirou a linha do ajax?!

<p:commandButton id="novo" value="Novo" onclick="novoDialogo.show()" type="button" /> <p:commandButton id="editar" value="Editar" onclick="novoDialogoEdit.show()" type="button" > <f:ajax render="modalTesteEditar" execute="@form" /> //RETIRAR </p:commandButton>

Olá…
Fiz um teste bem simples mas deu para entender o porque de não estar funcionando.

Teoricamente, quando eu uso o selection="#{testeBean.teste} o datatable ira setor o objeto selecionado dentro de “teste”. Para fazer isso acredito que ele invoque o met setTeste para setar o novo objeto, e getTeste para renderiza-lo no dialog.
Coloquei dois System.out.println, um no getTeste e outro no setTeste. No momento que eu seleciono a linha, o metodo “setTeste” não é invocado, porém, quando clico em editar e ele carrega o objeto “teste”, ele chama sim, o método getTeste. Vou tentar forçar que o datatable chame setTeste.

Obrigado

[quote=nana_ps]Vc retirou a linha do ajax?!

<p:commandButton id="novo" value="Novo" onclick="novoDialogo.show()" type="button" /> <p:commandButton id="editar" value="Editar" onclick="novoDialogoEdit.show()" type="button" > <f:ajax render="modalTesteEditar" execute="@form" /> //RETIRAR </p:commandButton> [/quote]

Sim, retirei sim.

Coloque tb essa linha abaixo do dataTable

<p:dataTable id="teste" var="teste" value="#{testeBean.testes}" selectionMode="single" selection="#{testeBean.teste}" rowKey="#{teste.id}" > <p:ajax event="rowSelect" update=":form" />

[quote=ThEDiegO]Olá…
Fiz um teste bem simples mas deu para entender o porque de não estar funcionando.

Teoricamente, quando eu uso o selection="#{testeBean.teste} o datatable ira setor o objeto selecionado dentro de “teste”. Para fazer isso acredito que ele invoque o met setTeste para setar o novo objeto, e getTeste para renderiza-lo no dialog.
Coloquei dois System.out.println, um no getTeste e outro no setTeste. No momento que eu seleciono a linha, o metodo “setTeste” não é invocado, porém, quando clico em editar e ele carrega o objeto “teste”, ele chama sim, o método getTeste. Vou tentar forçar que o datatable chame setTeste.

Obrigado[/quote]

Esses acessos estão certos, pelo get… setTeste não é para ser invocado, e vc já inicializou seu objeto aqui: private Teste teste = new Teste();

Eu uso o @PostConstruct para essa tarefa

@PostConstruct public void construct() { setTeste(new Teste()); }

Essa linha após o dataTable é para resolver… <p:ajax event=“rowSelect” update=":form" />

[quote=nana_ps][quote=ThEDiegO]Olá…
Fiz um teste bem simples mas deu para entender o porque de não estar funcionando.

Teoricamente, quando eu uso o selection="#{testeBean.teste} o datatable ira setor o objeto selecionado dentro de “teste”. Para fazer isso acredito que ele invoque o met setTeste para setar o novo objeto, e getTeste para renderiza-lo no dialog.
Coloquei dois System.out.println, um no getTeste e outro no setTeste. No momento que eu seleciono a linha, o metodo “setTeste” não é invocado, porém, quando clico em editar e ele carrega o objeto “teste”, ele chama sim, o método getTeste. Vou tentar forçar que o datatable chame setTeste.

Obrigado[/quote]

Esses acessos estão certos, pelo get… setTeste não é para ser invocado, e vc já inicializou seu objeto aqui: private Teste teste = new Teste();

Eu uso o @PostConstruct para essa tarefa

@PostConstruct public void construct() { setTeste(new Teste()); }

Essa linha após o dataTable é para resolver… <p:ajax event=“rowSelect” update=":form" />[/quote]

Perfeito nana_ps!! Agora esta funcionado!
O <p:ajax ajax evento=“RowSelect” /> serve para executar uma ação, que no caso é selection, e o update atualizado o form. Dessa forma estamos forçando o datatable a executar o selection?

Muito obrigado!

Apenas para registrar informação, tudo funcionol, porém, o dialog não vinha com as informações do objeto renderizado no inputText. Para resolver bastou inserir um update=“modalTesteEditar” no botão editar e o dialog foi carregado com o valor do objeto.

Obrigado a todos que ajudaram!

Pelo que eu entendi, é ao contrário, RowSelect faz uma solicitação ajax quando uma linha da tabela é selecionada. E como o selection já tem o objeto preenchido com os valores, ele indica através do update qual formulário deve ser atualizado com o valor recuperado.