[RESOLVIDO] JSF - Formulário de Edição

13 respostas
felipedantas89

Olá, sou novo em programação com JSF e tenho uma dúvida que está de matar, não encontro a solução em lugar algum.
Veja minha situação:
Tenho duas páginas, sendo uma página de listagem e uma com o formulário de cadastro e edição. Além disso tenho um Backingbean.
A listagem tem um botao de editar com o action para o bean e a tabela de listagem com o binding para o bean tambem.
O objeto é um Funcionario.
Ao ser escolhido uma linha o bean vai armazenar o funcionario recebido em um objeto e direcionar para a página de edição. Meu bean está com o scope setado como session.
O formulario de edição pega o objeto do mesmo bean.

Bem minha dúvida é a seguinte: Como que faço para que o mesmo formulário tanto crie um novo objeto quanto edite um objeto já existe?

13 Respostas

daviddjp

Cara…
nao sei se entendi direito sua pergunta mas se vc setar o value dos seus campos na tela de edicao com o objeto funcionario e ele estiver populado os campos aparecem populados, senão aparecem vazios.
Ou seja, como vc está usando escopo de sessão é só vc dar new no objeto antes de mandar pra tela de edicao/inclusão.

Espero que seja isso. ( apesar se eu achar que não é heheheh )

Abraco.

felipedantas89

Desculpe, eu não soube formular a pergunta com clareza.
Ignorando tudo o que falei, basta responder a simples questão: “Como criar um formulário de cadastro/edição (apenas um) e uma página de listagens com o botao de editar, de forma que não haja incompatibilidade entre NOVO e EDITAR”.

Expondo com mais detalhe a situação:
Imagine uma página com um menu e o menu com um item “Cadastro de Funcionario” com um link (sem passar pelo backingbean) para formfuncionario.jsf.
Temos também a listagem com o botão de editar, que direcionará para o bean que pegará o funcionário corrente, preencherá os campos necessários no bean e chamará formfuncionario.jsf.
Um exemplo de um campo no formulário:

<h:inputText value="#{funcBean.funcionario.nome}" />

do botao no formulário:

<h:commandButton value="Gravar" action="#{funcBean.gravar}" />

Problema 1: Como o bean vai saber que tipo de operação fazer no banco de dados (insert ou update)
Problema 2: O que aconteceria se eu clicasse em Editar (na listagem) - o que acarretaria no preenchimento da variavel funcionario - e dentro da página de editar eu clicasse no link de NOVO no menu. Como fazer para ele me trazer o formulário em branco para inserção de novos dados (isto é, agora eu daria um INSERT no banco de dados e não mais um update).

Obrigado a todos e especialmente a você daviddjp por responder minha pergunta.

daviddjp

Vamos la então por partes…

O seu bean tem escopo de sessão, ou seja, o que estiver dentro dele uma vez preenchido vai continuar preenchido durante toda a sessão.
O que vc tem que fazer ao clicar no link de novo é fazer

funcionario = new Funcionario;

Agora para saber se ao clicar no botão salvar voce vai alterar ou inserir é o seguinte, vc esta usando algum framework ORM do tipo hibernate ou ibates? Ta usando JPA?

Se não me engano o hibernate tem um metodo chamada insert ou update que já resolve isso para você.
Em JPA existe o metodo merge que tambem já resovle.

Caso não esteja usando a lógica é a seguinte:
No método que vc vai acionar quando clicar no botão salvar, vc pergunta se o Funcionario tem código ou não. Algo do tipo:

if ( funcionario.getCodigo() == null ) {
        salvar();
} else {
        atualizar();
}

Isso vai funcionar porque ao pesquisar o funcionario vc traz tambem seu código, e para atualizar primeiro vc tem que pesquisar.
Então sempre que tiver codigo ele vai saber que deve atualizar, caso contrário salva um novo.

Abraços!!

felipedantas89

Obrigado mais uma vez David, só tem você aqui :smiley:
Elogios a parte…

Você entendeu o meu problema, quase todo.
A dificuldade de salvar um novo ou update eu já havia resolvido.

Minha verdade dificuldade é a linha de código:

funcionario = new Funcionario();

Onde eu iria colocar isso, já que o link é direto pra página? Ele não passa por nenhum bean, já vai direto pra página formfuncionario.jsf

daviddjp

heheheh…

to demorando para responder pq a internet aqui no servico é bloqueada para quase tudo, mas enfim…

Tem como postar o codigo onde vc chama essa formfuncionario.jsf??

Vc faz mapeamento no faces-config… Navigation rule, navgation case… ?

felipedantas89

Faço os mapeamentos sim, mas não para esse caso, visto que o menu está presente em todas as páginas eu teria que fazer um mapeamento em todas as páginas para cada item do menu. Minha solução foi não usar o htmlcommandlink e usar HTML básico.
No menu eu tenho: <a href="formfuncionario.jsf">Cadastro de Funcionário</a> claro que isso é um exemplo de um item do menu, já que ele é grande e existem vários itens.

Uma segunda solução seria (acredito que não é possível) mapear todas as páginas de uma forma só. Isso é. Todo action que resultasse FUNCIONARIO seria direcionado para FORMFUNCIONARIO.JSF como default (acredito que isso não seja possível).

Está claro o problema? Eu uso HTML básico para direcionar o usuário para a página.

Jeferson_Manetti

olá…

bom o amigo acima ja te ajudou… mais vou dar minha opnião tamem… =)

tenho 2 jsp… lista.jsp e cad.jsp da um olhada ai…

cara aqui tem um jsp completo…

<!-- esse e o lista -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
<html>
<head>
	<link rel="shortcut icon" href="../favicon.ico" />
	<link rel="icon" type="image/gif" href="../animated_favicon1.gif" />
	<link rel="stylesheet" href="../../recursos/css/sistema_css.css" type="text/css" />
	<link rel="stylesheet" href="../../recursos/css/rounded_corners.css" type="text/css" />
	<script type="text/javascript" src="../../recursos/js/niftyLayout.js"></script>
	<script type="text/javascript" src="../../recursos/js/niftycube.js"></script>
	<title>Administrar Usuários</title>
</head>

<body>
<f:view>
	<div id="wrap"><jsp:include page="/include/header.jsp" />
	<div id="menu"><a4j:include viewId="/include/menu.jsp" /></div>
	<div id="mainBody"><h:form>
		<div id="icon-wrap"><h:commandLink
			action="#{usuarioHandler.novousuario}" styleClass="linkADD"
			value="Usuário">
		</h:commandLink></div>

		<div id="list-wrap"><rich:dataTable
			value="#{usuarioHandler.listaUsuarios}" var="usr" width="700px"
			columnClasses="center" rows="15" reRender="ds">

			<f:facet name="header">
				<h:outputText value="Usuários" />
			</f:facet>

			<rich:column sortBy="#{usr.nome}">
				<f:facet name="header">
					<h:outputText value="Nome" />
				</f:facet>
				<h:outputText value="#{usr.nome}" />
			</rich:column>

			<rich:column sortBy="#{usr.login}">
				<f:facet name="header">
					<h:outputText value="Login" />
				</f:facet>
				<h:outputText value="#{usr.login}" />
			</rich:column>

			<rich:column sortBy="#{usr.perfil.nome}">
				<f:facet name="header">
					<h:outputText value="Perfil" />
				</f:facet>
				<h:outputText value="#{usr.perfil.nome}" />
			</rich:column>

			<rich:column sortBy="#{usr.email}">
				<f:facet name="header">
					<h:outputText value="Email" />
				</f:facet>
				<h:outputText value="#{usr.email}" />
			</rich:column>

			<rich:column>
				<f:facet name="header">
					<h:outputText value="Editar" />
				</f:facet>
				<h:commandLink action="cad-usuario">
					<h:graphicImage value="/recursos/imagens/page_edit.png" />
					<f:setPropertyActionListener value="#{usr}"
						target="#{usuarioHandler.usuario}" />
				</h:commandLink>
			</rich:column>

			<rich:column>
				<f:facet name="header">
					<h:outputText value="Excluir" />
				</f:facet>
				<h:commandLink action="#{usuarioHandler.deletar}"
					onclick="return confirm ('Deseja Excluir?')">
					<h:graphicImage value="/recursos/imagens/remove.png" />
					<f:setPropertyActionListener value="#{usr}"
						target="#{usuarioHandler.usuario}" />
				</h:commandLink>

				<!--<h:graphicImage  value="/animated_favicon1.gif"/>-->

			</rich:column>

			<f:facet name="footer">
				<rich:datascroller id="ds"></rich:datascroller>
			</f:facet>
		</rich:dataTable></div>
	</h:form></div>
	<jsp:include page="/include/footer.jsp" /></div>
</f:view>
</body>
</html>
<!-- esse eo cad -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich" %>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<link rel="shortcut icon" href="../../favicon.ico"/>
	<link rel="stylesheet" href="../../recursos/css/cadastro_css.css" type="text/css" /> 
	<link rel="icon" type="image/gif" href="../../animated_favicon1.gif"/>
	<link rel="stylesheet" href="../../recursos/css/sistema_css.css" type="text/css" />
	<link rel="stylesheet" href="../../recursos/css/rounded_corners.css" type="text/css" /> 
	<script type="text/javascript" src="../../recursos/js/niftyLayout.js"></script>
	<script type="text/javascript" src="../../recursos/js/niftycube.js"></script> 
	<title>Cadastro Usuário</title>
</head>

<body>
<f:view>

	<div id="wrap"><jsp:include page="/include/header.jsp" />
	<div id="menu"><a4j:include viewId="/include/menu.jsp" /></div>
	<div id="mainBody">

	<fieldset><legend>Cadastro Usuário</legend> <h:form
		id="cadastro" styleClass="cadForm">

		<h:panelGrid columns="3">

			<h:outputText value="Nome:" styleClass="label" />
			<h:inputText label="Nome" id="nome" required="true"
				value="#{usuarioHandler.usuario.nome}">
				<rich:ajaxValidator event="onblur" />
			</h:inputText>
			<rich:message for="nome">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>


			<h:outputText value="Login:" styleClass="label" />
			<h:inputText label="Login" id="login" required="true"
				value="#{usuarioHandler.usuario.login}">
				<rich:ajaxValidator event="onblur" />
				<f:validator validatorId="LoginValidator"/>
			</h:inputText>
			<rich:message for="login">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>

			<h:outputText value="Senha:" styleClass="label" />
			<h:inputSecret label="Senha" id="password" required="true"
				value="#{usuarioHandler.usuario.senha}">
				<rich:ajaxValidator event="onblur" />
			</h:inputSecret>
			<rich:message for="password">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>

			<h:outputText value="E-mail:" styleClass="label" />
			<h:inputText label="E-mail" id="email"
				value="#{usuarioHandler.usuario.email}">
				<rich:ajaxValidator event="onblur" />
			</h:inputText>
			<rich:message for="email">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>

			<h:outputText value="Perfil:" styleClass="label" />
			<h:selectOneMenu label="Perfil" id="perfil"
				value="#{usuarioHandler.usuario.perfil}">
				<f:selectItems value="#{usuarioHandler.perfisComboBox}" />
				<f:converter converterId="PerfilUsuarioConverter" />
			</h:selectOneMenu>
			<rich:message for="perfil">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>

			<h:outputText value="Descrição:" styleClass="label" />
			<h:inputTextarea label="Descrição" id="descricao"
				value="#{usuarioHandler.usuario.descricao}" />
			<rich:message for="descricao">
				<f:facet name="passedMarker">
					<h:graphicImage value="/recursos/imagens/passed.gif" />
				</f:facet>
				<f:facet name="errorMarker">
					<h:graphicImage value="/recursos/imagens/error.gif" />
				</f:facet>
			</rich:message>

		</h:panelGrid>

		<br />
		<h:panelGrid columns="2" styleClass="ButtonBox">
			<h:commandButton action="#{usuarioHandler.salvar}" value="Salvar" />
			<h:commandButton action="#{usuarioHandler.voltar}" immediate="true"
				value="Voltar" />
		</h:panelGrid>

	</h:form></fieldset>

	</div>
	<jsp:include page="/include/footer.jsp" /></div>
</f:view>
</body>
</html>

aqui ta o manegedbean

public class UsuarioHandler {
	
	private Usuario usuario;

	 
	/******************* Method ****************/
	public UsuarioHandler() {
		usuario = new Usuario();		
	}
	
	public String novousuario(){
		usuario = new Usuario();
		return "cad-usuario";
	}
	
	public String voltar(){	
		return "lista-usuario";
	}
	
	public String salvar() throws Exception{

                /** aqui eu uso o hiberbate...
                * então utilizo o SaveOrUpdate() 
                * que faz basicamente o seguinte ele verifica se o Obj tem ID... 
                * caso tenha ele atualiza senão ele salva
                * seria basicamente oq o amigo acima disse
                * if ( funcionario.getCodigo() == null ) {  
                *         salvar();  
                * } else {  
                        atualizar();  
                * }
                * */  
		UsuarioService.salvarOuAtualizarUsuario(usuario);
				
		usuario = new Usuario(); 

		return "lista-usuario";
	}
	
	public String deletar() throws Exception{

		UsuarioService.deletarUsuario(usuario);

		return "lista-usuario";
	}
	
	public List<SelectItem> getPerfisComboBox()throws Exception{

		List<PerfilUsuario> listaPerfil = PerfilUsuarioService.getListPerfil();
		List<SelectItem> lista = new ArrayList<SelectItem>();
		
		for (PerfilUsuario perfil : listaPerfil) {
			lista.add(new SelectItem(perfil, perfil.getNome()));
		}
				
		return lista;
	}
		
	
	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public List<Usuario> getListaUsuarios() throws Exception {		
		return UsuarioService.getListUsuario();
	}

bom e isso ai da uma olhadinha blz

felipedantas89

Bom ver que alguem já tentou fazer o mesmo que eu =D
Jeferson, seu código está claro.
Mas minha dúvida é: onde você chama o método novoUsuario();

daviddjp

Tem como mapear todas as paginas sim cara…

Não me lembro 100% mas é algo assim

<navigation-case>   
    <from-view-id>*</from-action>   
    <from-outcome>funcionar</from-outcome>   
    <to-view-id>/suaPagina.jsp</to-view-id>           
</navigation-case>

Não tenho certeza se os nomes são esses… parei de mexer com jsf.
Mas a questão é assim. no lugar onde vc diz de que página vai vir a resposta, coloca *. Dai de todo lugar do teu projeto que vier funcionario ele direciona para a pagina que vc escolheu

Jeferson_Manetti

felipedantas89:
Bom ver que alguem já tentou fazer o mesmo que eu =D
Jeferson, seu código está claro.
Mas minha dúvida é: onde você chama o método novoUsuario();

aqui…

<div id="icon-wrap">
    <h:commandLink  
       action="#{usuarioHandler.novousuario}" styleClass="linkADD"  
       value="Usuário">  
    </h:commandLink>
</div>

segue alguns prints em anexo…

felipedantas89

David e Jeferson, muitíssimo obrigado.
Vocês me ajudaram demais.
David orbigado porque eu não sabia que esse maldito asterisco era permitido nos mapeamentos e isso me ajudou na montagem do menu (não precisar mapear para todas as classes) e agora eles irão direcionar para o método que o Jeferson ajudou aí.
Valeu aos dois.

felipedantas89

Como marcar o tópico como resolvido?

Jeferson_Manetti

opa estamos aqui pra isso ajudar uns aos outros…

agora e só pagar um café q fica td certo… kkkk

a respeito de fechar o topico… eu não sei mais tipo tenta editar o nome e coloca [RESOLVIDO]

blz t+

Criado 23 de julho de 2009
Ultima resposta 24 de jul. de 2009
Respostas 13
Participantes 3