(RESOLVIDO)Enviar registro selecionado de uma p:dataTable para o formulário, JSF primefaces

Olá, estou migrando de Struts1 para o JSF, estou começando agora com JSF primefaces e gostaria de pedir uma ajuda.
Estou desenvolvendo uma tela de cadastro de usuário, que tem um formulário e uma tabela. Eu gostaria que quando eu selecionasse um registro da p:dataTable, os dados desse registro selecionado fossem para os campos do formulário.
Eu já fiz isso com struts, mas utilizando JSF primefaces eu não sei como fazer.

Código da página:

<h:body>
       <h:form>
            <p:messages id="messages" showDetail="true"  autoUpdate="true" closable="true" />
            <p:panelGrid columns="2"  style="horizontal-align:center">
                  <p:outputLabel for="id" value="ID:" />
                  <p:spinner id="id" value="#{UsuarioMB.usuario.id}" />  
                  <p:outputLabel for="nome" value="Nome:" />
                  <p:inputText id="nome" value="#{UsuarioMB.usuario.nome}" />    
                  <p:outputLabel for="senha" value="Senha:" />
                  <p:inputText id="senha" value="#{UsuarioMB.usuario.senha}" />  
                  <p:outputLabel for="descricao" value="Descrição:" />
                  <p:inputTextarea id="descricao"
                       value="#{UsuarioMB.usuario.descricao}" /> 
   				<p:outputLabel for="dataCadastro" value="DataCadastro:" />
                 <p:calendar value="#{UsuarioMB.usuario.dataCadastro}" locale="pt_BR"
				id="dataCadastro" showButtonPanel="true">
				<f:convertDateTime pattern="dd/MM/yyyy" />
			</p:calendar>
   	            <p:commandButton  value="Cadastrar" icon="ui-icon-star"  action= "#{UsuarioMB.cadastraUsuario}"   update="tabela,messages,@form"   >
                   </p:commandButton> 
                    <p:commandButton  value="Consultar" icon="ui-icon-star"  action= "#{UsuarioMB.consultar}"   update="tabela,messages"   >
                    </p:commandButton> 
                    <p:commandButton  value="Limpar" icon="ui-icon-star" action= "#{UsuarioMB.limpar}"  update="tabela"  type="reset"    >
                   </p:commandButton> 
            </p:panelGrid> 
      <p:dataTable id="tabela" var="usuario" value="#{UsuarioMB.lista}"
		paginator="true" rows="50" emptyMessage="Não há registros na lista"
		paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
		rowsPerPageTemplate="10,15,25,50,100">
		<f:facet name="header">Lista de usuários</f:facet>
		<p:column headerText="ID" style="width: 10%;"
			sortBy="#{usuario.id}">
			<h:outputText value="#{usuario.id}"  rowkKey="#{UsuarioMB.usuario.id}"  /> 
		</p:column>
		<p:column headerText="Nome" style="width: 25%;" sortBy="#{usuario.nome}">	<h:outputText value="#{usuario.nome}" />
		</p:column>
		<p:column headerText="Descrição" style="width: 25%;" sortBy="#{usuario.descricao}">
			<h:outputText value="#{usuario.descricao}" /></p:column>
		<p:column headerText="Data de Cadastro" style="width: 25%;" sortBy="#{usuario.dataCadastro}">
			<h:outputText value="#{usuario.dataCadastro}" />
		</p:column>
	</p:dataTable>
       </h:form>
  </h:body>

Me desculpem as falhas, obrigado galera
Abs

Amigo, você o formulário a ser preenchido está na mesma ou em outra página?

Esta na mesma página, obrigado.
Esse aqui.

<p:panelGrid columns="2" style="horizontal-align:center">
<p:outputLabel for="id" value="ID:" />
<p:spinner id="id" value="#{UsuarioMB.usuario.id}" /> 
<p:outputLabel for="nome" value="Nome:" />
<p:inputText id="nome" value="#{UsuarioMB.usuario.nome}" /> 
<p:outputLabel for="senha" value="Senha:" />
<p:inputText id="senha" value="#{UsuarioMB.usuario.senha}" /> 
<p:outputLabel for="descricao" value="Descrição:" />
<p:inputTextarea id="descricao"
value="#{UsuarioMB.usuario.descricao}" /> 
<p:outputLabel for="dataCadastro" value="DataCadastro:" />
<p:calendar value="#{UsuarioMB.usuario.dataCadastro}" locale="pt_BR"
id="dataCadastro" showButtonPanel="true">
<f:convertDateTime pattern="dd/MM/yyyy" />
</p:calendar>
<p:commandButton value="Cadastrar" icon="ui-icon-star" action= "#{UsuarioMB.cadastraUsuario}" update="tabela,messages,@form" >
</p:commandButton> 
<p:commandButton value="Consultar" icon="ui-icon-star" action= "#{UsuarioMB.consultar}" update="tabela,messages" >
</p:commandButton> 
<p:commandButton value="Limpar" icon="ui-icon-star" action= "#{UsuarioMB.limpar}" update="tabela" type="reset" >
</p:commandButton> 
</p:panelGrid>

Uma forma seria você adicionar mais uma coluna do datable com um botão, assim ao clicar no botão ele setária o usuário do registro em um usuário no MB. Segue exemplo.

<p:column headerText="Editar" style="width: 25%;" sortBy="#{usuario.dataCadastro}">
	<p:commandButton icon="iconConfirm" action="#{UsuarioMB.setUsuario(usuario)}" update="panelGrid"/>
</p:column>

Nota esse usuário que estou passando por parâmentro é variával var=“usuario” criado pelo dataTable.

Obs: No button eu dei um update no panelGrid, para que isto funcione será necessário dar um id para o panelGrid em questão, e substir o update=“panelGrid” por update=“IdDoPanelGrid”

1 curtida

Outra forma seria através a tag <f:setPropertyActionListener do JSF, dentro do commandButton do primefaces, usando o atributo do usuario, no controller.

<p:column>
       <p:commandButton value="Atualizar usuário" id="btAtualizaUsuario" update=":formDialogAtualizaUsuario" >
                   <f:setPropertyActionListener for="btAtualizaUsuario" target="#{usuarioBean.usuario}"
                                                                 value="#{usuario}"/>
        </p:commandButton>
</p:column>
1 curtida

Essa forma funcionou também, só estou tentando uma forma que seja mais discreto na datatable. Fiz com commandLink também

<p:commandLink  id="ajax" update="@form" actionListener="#{UsuarioMB.setUsuario(usuario)}">
               <h:outputText value="#{usuario.nome}" />
</p:commandLink>

Agradeço a ajuda.

Legal, vou tentar dessa forma também.
Até agora fiz dessa forma

<p:commandLink  id="ajax" update="@form" actionListener="#{UsuarioMB.setUsuario(usuario)}">
               <h:outputText value="#{usuario.nome}" />
</p:commandLink>

Valew

Data Table com Selection

Se liga no exemplo co o seguinte cabeçalho “Select Events”

Nesse caso você pode disparar ações no evento de seleção ou rejeição das linhas do grid.

1 curtida

Opa, valew, funcionou:

<p:dataTable id="tabela" var="usuario" value="#{UsuarioMB.lista}"
		paginator="true" rows="10" emptyMessage="Não há registros na lista"
		paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
		rowsPerPageTemplate="10,15,25,50,100"  rowKey="#{usuario.id}" selection="#{UsuarioMB.usuario}" selectionMode="single" >
		<f:facet name="header">Lista de usuários</f:facet>
		<p:ajax event="rowSelect" listener="#{UsuarioMB.onRowSelect}"  update="@form" />  
		<p:column headerText="ID" style="width: 10%;" sortBy="#{usuario.id}" >
				 <h:outputText value="#{usuario.id}" />  
		</p:column>
		<p:column headerText="Nome" style="width: 25%;" sortBy="#{usuario.nome}"> 
               <h:outputText value="#{usuario.nome}" />  
		</p:column>
		<p:column headerText="Descrição" style="width: 25%;" sortBy="#{usuario.descricao}">
			<h:outputText value="#{usuario.descricao}" /></p:column>
		<p:column headerText="Data de Cadastro" style="width: 25%;" sortBy="#{usuario.dataCadastro}">
			<h:outputText value="#{usuario.dataCadastro}" />
		</p:column> 
	</p:dataTable>`

public void setUsuario(Usuario usuario) {
          this.usuario = usuario;
     }
         
     public void onRowSelect(SelectEvent event) { 
    	 setUsuario( (Usuario) event.getObject()); 
     }

Obrigado gente

Agora esta acontecendo outro problema, o objeto Usuario esta com valor null quando faço uma consulta ou quando eu faço um insert

public class UsuarioDAO {
	Connection con = null;
	Conexao conexao = null;
	/**
	 * 
	 */
	public UsuarioDAO() {
		  conexao = Conexao.getInstance();
		
		// TODO Auto-generated constructor stub
	}
	 public void closeConnection() throws SQLException {		   
         con.close();
    }
	// cadastral no banco um usuario passado como parametro
    public boolean insertUsuario(Usuario usuario) {
         Statement st = null;
         ResultSet rs = null;
         try {
        	   try {
				con = conexao.getConnectionNetWork();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
               st = con.createStatement();

               PreparedStatement preparedStatement = con
                         .prepareStatement("insert into usuario_teste123(id, nome, senha, descricao, data_cadastro) values(?,?,?,?,?)");
               preparedStatement.setInt(1, usuario.getId());
               preparedStatement.setString(2, usuario.getNome());
               preparedStatement.setString(3, usuario.getSenha());
               preparedStatement.setString(4, "" + usuario.getDescricao());
               preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));

               preparedStatement.execute();
               return true;
         } catch (SQLException ex) {
               Logger lgr = Logger.getLogger(UsuarioDAO.class.getName());
               lgr.log(Level.SEVERE, ex.getMessage(), ex);
               return false;
         }
    }
    
    //lista todos os usuarios cadastrados no banco de dados
    public List<Usuario> listUsuarios() {
         ArrayList<Usuario> lista = new ArrayList<Usuario>();
         Statement st = null;
         ResultSet rs = null;
         try {
        	 try {
 				con = conexao.getConnectionNetWork();
 			} catch (Exception e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
               st = con.createStatement();
               String sql = "select * from usuario_teste123 order BY ID desc  ";
              rs = st.executeQuery(sql);

               while (rs.next()) {
                    Usuario usuario = new Usuario();
                    usuario.setId(rs.getInt(1));
                    usuario.setNome(rs.getString(2));
                    usuario.setSenha(rs.getString(3));
                    usuario.setDescricao(rs.getString(4));
                    usuario.setDataCadastro(rs.getDate(5));
                    lista.add(usuario);
               }

         } catch (SQLException ex) {
               Logger lgr = Logger.getLogger(UsuarioDAO.class.getName());
               lgr.log(Level.SEVERE, ex.getMessage(), ex);

         } finally {
               try {
                    if (rs != null) {
                         rs.close();
                    }
                    if (st != null) {
                         st.close();
                    }
                    if (con != null) {
                         con.close();
                    }

               } catch (SQLException ex) {
                    Logger lgr = Logger.getLogger(UsuarioDAO.class.getName());
                    lgr.log(Level.WARNING, ex.getMessage(), ex);
               }
         }
         return lista;
    }
    
    
    //lista todos os usuarios cadastrados no banco de dados
    public List<Usuario> consultar(Usuario us) {

         ArrayList<Usuario> lista = new ArrayList<Usuario>(); 
         ResultSet rs = null;
         PreparedStatement pstmt = null;
         StringBuffer query = new StringBuffer();
         query.append(" select * from usuario_teste123 ");         
         query.append(" WHERE ");
                 
         if(  us.getId()  != null) {
        	 query.append("  ID = " + us.getId()+ "");
         }
                  if( !"".equalsIgnoreCase(us.getNome()) && !"".equalsIgnoreCase(us.getNome())) {
        	 query.append("AND  NOME = '" + us.getNome()+ "'");; 	
         }
                  
         if( !"".equalsIgnoreCase(us.getDescricao()) && !"".equalsIgnoreCase(us.getDescricao())) {
        	 query.append(" AND DESCRICAO = '" + us.getDescricao()+ "'");; 	
         }
         
         if( !"".equalsIgnoreCase(us.getSenha()) && !"".equalsIgnoreCase(us.getSenha())) {
        	 query.append(" AND SENHA = " + us.getSenha()+ "");; 	
         }
         
         query.append(" order BY ID desc ");

         try {
        	 try {
 				con = conexao.getConnectionNetWork();
 			} catch (Exception e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
               
               System.out.println(query.toString());
               pstmt = con.prepareStatement(query.toString());
               
              rs = pstmt.executeQuery();
               while (rs.next()) {

                    Usuario usuario = new Usuario();
                    usuario.setId(rs.getInt(1));
                    usuario.setNome(rs.getString(2));
                    usuario.setSenha(rs.getString(3));
                    usuario.setDescricao(rs.getString(4));
                    usuario.setDataCadastro(rs.getDate(5));
                    lista.add(usuario);
               }

         } catch (SQLException ex) {
               Logger lgr = Logger.getLogger(UsuarioDAO.class.getName());
               lgr.log(Level.SEVERE, ex.getMessage(), ex);

         } finally {
               try {
                    if (rs != null) {
                         rs.close();
                    }
                  
                    if (con != null) {
                         con.close();
                    }

               } catch (SQLException ex) {
                    Logger lgr = Logger.getLogger(UsuarioDAO.class.getName());
                    lgr.log(Level.WARNING, ex.getMessage(), ex);
               }
         }
         return lista;
    }
}

Posta o ManagedBean. Provavelmente é o scopo dele, se estiver como @RequestScope(valor default caso não tenha um valor definido) recomendo usar @ViewScope ele mantém seu MB vivo enquanto a página está aberta, assemelhasse mais ao ciclo de vida de uma aplicação desktop.

E recomendo também assim que tiver um pouco de experiência com JSF, passar a utilizar CDI e JPA. Gaaranto que vai faciltar e agilizar muito sua vida. Não recomendo iniciar diretamente pois o CDI camufla alguns erros, sendo dificil achar a origem a menos que já tenha uma boa experiência com JSF.

Não sabia desses detalhes, vou me lembrar para as próximas, segue meu ManagedBean:

@ManagedBean(name="UsuarioMB")
@ViewScoped
public class UsuarioManagedBean  implements java.io.Serializable {     
     /**
	 * 
	 */
	private static final long serialVersionUID = 320054925202954008L;
	private Usuario usuario;
	private List<Usuario> lista = new ArrayList<Usuario>();     
	
	public UsuarioManagedBean() {
		usuario = new Usuario();
		listar();
	}
	public void removeBean(String bean){
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(bean);
    }
	//Metodo para persistir
     public String cadastraUsuario() throws SQLException {        
              
                UsuarioDAO dao = new UsuarioDAO();
                    if (dao.insertUsuario(usuario)) {
                	listar(); 
                     FacesContext.getCurrentInstance().addMessage(
                               null, new FacesMessage(FacesMessage.SEVERITY_INFO,"Sucesso! Usuário cadastrado com sucesso!", "Usuário cadastrado com sucesso!"));
                } else {
                     FacesContext.getCurrentInstance().addMessage(
                               null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Erro!", "Erro no cadastr de usuário!"));
 
                }
                dao.closeConnection();                 
          return "";
     }
     
     public void consultar(){    	 
    	   UsuarioDAO dao = new UsuarioDAO();
    	   System.out.println("Consultar Usuario");
    	   lista =  dao.consultar(usuario);    
     }
     
     public void listar() {
    	 UsuarioDAO dao = new UsuarioDAO();
 		System.out.println("Listar Usuario");
 		lista = dao.listUsuarios();
 	}
     
     public void limpar() {
 		System.out.println("Limpar");
 		System.out.println(usuario);
 		usuario = new Usuario();
 	}
     
     public void setLista(List<Usuario> lista) {
 		this.lista = lista;
 	}
     public List<Usuario> getLista()   throws SQLException {
 		return lista;
 	}
     public List<Usuario> getUsuarios() throws SQLException {
          UsuarioDAO dao = new UsuarioDAO();
          List<Usuario> listaUsuarios = dao.listUsuarios(); 
          return listaUsuarios;
     }
      public Usuario getUsuario() {
          return usuario;
     }     
     public void setUsuario(Usuario usuario) {
          this.usuario = usuario;
     }
     public void onRowSelect(SelectEvent event) { 
    	 setUsuario( (Usuario) event.getObject()); 
     }      
}

Mas funcionou agora?

O cadastro no banco ainda não, o objeto usuario fica null quando tento persistir

Descobri que quando eu não utilizo o ajax para enviar os dados para o formulário, então funciona o insert;

<p:ajax event="rowSelect" listener="#{UsuarioMB.onRowSelect}" update="@form" />

descobri que quando eu tiro o update="@form" o objeto fica preenchido e funciona