Envio de formulário sem refresh com JQuery/PHP

Olá pessoal, tudo bom? Hoje, nesse artigo que foi sugerido, irei abordar mais uma opção de fazer uma requisição AJAX, agora com JQuery.

Como exemplo vou utilizar uma página onde o usuário pode deixar sua mensagem sem precisar dar refresh na página. Os arquivos estão disponíveis para download no final do arquivo. Vamos lá.

Veja o código em funcionamento

1. Banco de dados

Primeiramente, como sempre, vamos criar nossa base de dados e inserir alguns registros de exemplo:

CREATE TABLE IF NOT EXISTS `mensagens` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(50) NOT NULL,
  `email` varchar(50) NOT NULL,
  `mensagem` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
 
INSERT INTO `mensagens` (`id`, `nome`, `email`, `mensagem`) VALUES
(1, 'faael', 'faelcalves@hotmail.com', 'Hello world!'),
(2, 'Fulano', 'fulano@dominio.com', 'Olá Mundo!');

2. Conexão (conn.php)

Vamos criar também o arquivo responsável pela conexão com nosso banco de dados:

<?php
// Informações para conexão
$host = "localhost";
$usuario = "root";
$senha = "senha";
$banco = "banco";
// Realizando conexão e selecioando banco de dados
$conn = mysql_connect($host, $usuario, $senha) or die(mysql_error());
$db = mysql_select_db($banco, $conn) or die(mysql_error());
// Alterando o charset para utf8, para evitar problemas de acentuação
mysql_set_charset('utf8');
?>

Edite as informações de acordo com as configurações de seu banco de dados

3. A página (index.php)

Criaremos a base da nossa página, com algumas divs e o formulário:

<?php require_once("conn.php"); ?>
<!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">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Envio de formulário sem refresh com JQuery/PHP</title>
</head>
 
<body>
<h1>Escrever Mensagem</h1>
 
<div id="status" style="display: none;"></div>
 
<div id="escrever">
	<form id="formulario" action="javascript:func()" method="post">
	    <strong>Nome:</strong> <br />
        <input name="nome" type="text" id="nome" size="35" /> <br /><br />
 
	    <strong>Email:</strong> <br />
        <input name="email" type="text" id="email" size="35" /> <br /><br />
 
	    <strong>Mensagem:</strong>  <br />
	    <input name="mensagem" type="text" id="mensagem" size="145" /><br /><br />
 
        <input type="submit" value="Enviar" />
 
    </form>
</div>
 
<h1>Mensagens</h1>
 
<div id="mensagens"></div>
 
</body>
</html>

Bom, agora vamos começar a trabalhar. Primeiramente, iremos baixar a biblioteca do jquery, clique aqui para baixar. Depois de baixado, vamos incluí-lo na nossa página, entre as tags <head></head>:

<script type="text/javascript" language="javascript" src="jquery-1.3.2.js"></script>

Inserido o jquery, vamos colocar as mensagens do banco de dados na div mensagens:

<div id="mensagens">
	<?php
	// Buscamos e exibimos as mensagens já contidas no banco de dados
	$query = mysql_query("SELECT * FROM mensagens ORDER BY id DESC");
	while($mensagem = mysql_fetch_object($query)) {
		echo "<strong>" . $mensagem->nome . "</strong> disse: <em>" . $mensagem->mensagem . "</em><br />";
	}
	?>
</div>

Retornando no jquery, vamos agora criar a função que fará a requisição ajax, essa deverá estar entre as tags <head></head> também:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script type="text/javascript" language="javascript">
$(function($) {
	// Quando o formulário for enviado, essa função é chamada
	$("#formulario").submit(function() {
		// Colocamos os valores de cada campo em uma váriavel para facilitar a manipulação
		var nome = $("#nome").val();
		var email = $("#email").val();
		var mensagem = $("#mensagem").val();
		// Exibe mensagem de carregamento
		$("#status").html("<img src='loader.gif' alt='Enviando' />");
		// Fazemos a requisão ajax com o arquivo envia.php e enviamos os valores de cada campo através do método POST
		$.post('envia.php', {nome: nome, email: email, mensagem: mensagem }, function(resposta) {
				// Quando terminada a requisição
				// Exibe a div status
				$("#status").slideDown();
				// Se a resposta é um erro
				if (resposta != false) {
					// Exibe o erro na div
					$("#status").html(resposta);
				} 
				// Se resposta for false, ou seja, não ocorreu nenhum erro
				else {
					// Exibe mensagem de sucesso
					$("#status").html("Mensagem enviada com sucesso!");
					// Coloca a mensagem no div de mensagens
					$("#mensagens").prepend("<strong>"+ nome +"</strong> disse: <em>" + mensagem + "</em><br />");
					// Limpando todos os campos
					$("#nome").val("");
					$("#email").val("");
					$("#mensagem").val("");
				}
		});
	});
});
</script>

É nessa função que praticamente tudo acontece. Vou tentar detalhar mais ela:

Linha 4: Chamamos a função quando o formulário é enviado, ou seja, no evento submit.

Linha 6,7,8: Colocamos os valores de cada campo do formulário em uma variável correspondente, para que assim facilite a manipulação desses valores.

Linha 10: Colocamos na div status a imagem de “carregando”. Você pode criar seus próprios “loaders” no ajaxload.info.

Linha 12: É aqui que chamamos o arquivo envia.php que fará a validação dos dados e, se corretos, a adição dos mesmos no banco de dados. No primeiro parâmetro, passamos o arquivo, no caso o envia.php; No segundo passamos os valores que serão passados pelo método POST; No terceiro chamamos a função que tratará da resposta no final da requisição.

Linha 15: Exibimos a div status com o efeito slideDown(); Lembrando que o display da div deve ser none, senão não haverá efeito.

Linha 17: Verificamos se a resposta é diferente de false, ou seja, se houve algum erro.

Linha 19: Se houver erro, a mensagem de erro é colocado na div status.

Linha 22: Se não houver nenhum erro na validação.

Linha 25: Colocamos na div status uma mensagem de sucesso.

Linha 27: Colocamos na div mensagens a nova mensagem que foi enviada. A propriedade prepend adiciona um conteúdo antes do conteúdo original da div.

Linha 29,30,31: Limpamos os campos do formulário.

4. PHP (envia.php)

Só restou criar o envia.php, que fará toda a validação dos dados e irá adicioná-los no banco de dados, pra quem conhece php, creio que não terá nenhuma novidade:

<?php
// Incluimos o arquivo de conexão
require_once("conn.php");
// Recuperamos os valores dos campos através do método POST
$nome = $_POST["nome"];
$email = $_POST["email"];
$mensagem = $_POST["mensagem"];
// Verifica se o nome foi preenchido
if (empty($nome)) {
	echo "Escreva seu nome";
} 
// Verifica se o email é válido
elseif (!eregi("^[a-z0-9_\.\-]+@[a-z0-9_\.\-]*[a-z0-9_\-]+\.[a-z]{2,4}$", $email)) {
	echo "Digite um email válido";
} 
// Verifica se a mensagem foi digitada
elseif (empty($mensagem)) {
	echo "Escreva uma mensagem";
} 
// Verifica se a mensagem nao ultrapassa o limite de caracteres
elseif (strlen($mensagem) > 140) {
	echo "A mensagem deve ter no máximo 140 caracteres";
} 
// Se não houver nenhum erro
else {
	// Inserimos no banco de dados
	$query = mysql_query("INSERT INTO mensagens VALUES ('', '".$nome."', '".$email."', '".$mensagem."')");
	// Se inserido com sucesso
	if ($query) {
		echo false;
	} 
	// Se houver algum erro ao inserir
	else {
		echo "Não foi possível inserir a mensagem no momento.";
	}
}
?>

Aqui simplesmente verificamos se os dados são válidos e retornamos apenas uma resposta, ou seja, uma mensagem de erro ou um “false” (Esse valor define que tudo está correto);

5. Conclusão

Bom pessoal, é isso; tentei explicar da melhor forma possível de forma rápida. Espero que vocês tenham entendido, qualquer dúvida só entrar em contato, ok?

Download dos arquivos

Abraços.

115 comments

  1. Olá, muito bom o script, eu não estou conseguindo formatar a div #status por que ? Mudar a cor etc, estou atacando a mesma no css mas nada acontece.. por que isso acontece ?

  2. Rafael estou tendo uma dificuldade de enviar radio e checbox usando seu script …quando envio ele sempre marca “on” na duas opcoes. ex se eu colocar dois checkbox e enviar eloe vai mandar ON ON sendo que so marquei um campo. como resolver?

  3. Existe como ao inves de pegar campo a campo do formulario no post mandarmos o form inteiro? Por que nos casos onde temos formularios grandes teriamos muito trabalho…

  4. Cara! Mto massa esse script! Tá funcionando show de bola!
    Me tira uma dúvída… se este sistema de msg fosse um chat, como q eu buscaria os dados no BD? Tipo o twitter, ele mostra o retorno do BD mesmo se for outra pessoa postando… Sabe explicar? Vlw Abraço

    • Olá Elio,

      O jeito mais simples de se fazer isso é criar um timer que a cada X segundos busca por mensagens novas no banco de dados. Dê uma pesquisada na função setInterval() do javascript, você pode começar por ai.

      Abraço.

  5. Rafael,

    Estou desenvolvendo uma aplicação me orientando por este e outros post (php, jquery). O sistema funciona assim, ao clicar no link ele exclui um registro da base de dados, se realizado com sucesso eu altero a classe do link para “OK” ou “ERRO” em caso de erro.

    O jquery está assim, porém não está alterando a classe.

    $(function($){
        $("ul#nav a").click(function(){
            var atualiza = $(this).attr('href');
            $.post('envia.php', {
                atualiza: atualiza
            },
            function(resposta) {
                if (resposta != false) {
                    $(this).addClass("ok");
                }
                else {
                    $(this).addClass("erro");
                }
            })
            return false;
        })
    });
    

    Quero alterar somente o link que foi clicado. Valeu!

    • Olá Fabio,

      Creio que o problema seja o escopo do this, como ele está dentro da função está se referênciando a ela.
      Acredito que você possa armazenar o objeto e então utilizá-lo posteriormente, por exemplo:

      $(function($){
          $("ul#nav a").click(function(){
              var atualiza = $(this).attr('href');
              var obj = $(this);
              $.post('envia.php', {
                  atualiza: atualiza
              },
              function(resposta) {
                  if (resposta != false) {
                      obj.addClass("ok");
                  }
                  else {
                      obj.addClass("erro");
                  }
              })
              return false;
          })
      });

      Abraço.

  6. olá, é por que eu baixei o codigo fonte e criei o banco de dados de acordo com o codigo fonte, mais não esta enviando de geito nehum os dados para o banco, quando clico em enviar só da a mensagem:
    Não foi possível inserir a mensagem no momento.

    como resolvo esse problema?

    obrigado!!!

  7. Rafael, cara não sei o que ta acontecendo, pois o formulario não envia os dados para o banco só da a mensagem:
    Não foi possível inserir a mensagem no momento.
    e o pior é que o codigo fonte é o seu eu só mudei o nome do banco o usuario e senha.

    • Olá Emmanuel,

      Deve ser algum problema no insert ou então na conexão com o bando de dados. Para ver o erro exato, em vez de exibir a mensagem “Não foi possível inserir a mensagem no momento.”, faça assim:

      if ($query) {
      	echo false;
      } 
      // Se houver algum erro ao inserir
      else {
      	echo mysql_error();
      }

      Abraço.

    • Olá Romulos, tudo bom?

      Bom, pelo que entendi, acredito que o problema esteja no seu acao_busca.php, pois é ele quem retorna aquela tabela, será que ele não está retornando sempre o mesmo resultado, independente do que eu digitar?

      Uma observação: para não ficar empilhando as tabelas no retorno, utilize .html() ao invés .append().

      Legal você ter gravado um vídeo com o problema, se todo mundo fosse claro assim nas dúvidas seria mais fácil ajudar.
      Abraço.

  8. Meu Caro amigo, seu posto foi mto bom, mas existe um erro muito grave mas mto simples de se resolver. O usuário pode clicar várias vezes no enviar e ele submita o formulario várias vezes com o mesmo conteudo. enfim, seria mto bom se voce arrumasse o seu poste para corrigir isso que pode mtas vzs passar despercebido por qualquer um. Se quiser que eu passe o que eu mudei entre em contato no meu email. Abrasso. Obrigado

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">