Sistema de votação simples com PHP/JQuery/AJAX

Olá pessoal, hoje vamos montar um sistema de votação bem simples. Irei utilizar como exemplo uma página com algumas frases e o usuário poderá escolher o que ele achou da frase: bom ou ruim. Tudo isso sem refresh na página, claro. Vamos lá?

Veja o resultado final aqui

Os arquivos estão disponibilizados para download no fim do artigo.

1. Banco de dados

Primeiramente vamos criar nossa tabela no banco de dados e inserir alguns registros:

CREATE TABLE IF NOT EXISTS `frases` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `texto` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  `bom` int(11) DEFAULT NULL,
  `ruim` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=6;

INSERT INTO `frases` (`id`, `texto`, `bom`, `ruim`) VALUES
(1, '"A imaginação é mais importante que o conhecimento."', 0, 0),
(2, '"O mundo não está ameaçado pelas pessoas más, e sim por aquelas que permitem a maldade."', 0, 0),
(3, '"Tente mover o mundo - o primeiro passo será mover a si mesmo."', 0, 0),
(4, '"Os homens erram, os grandes homens confessam que erraram."', 0, 0),
(5, '"Só os mortos conhecem o fim da guerra."', 0, 0);

2. Arquivo de conexão (conn.php)

Como de costume, vamos fazer a conexão com o banco de dados:

// Informações para conexão
$host = "localhost";
$usuario = "root";
$senha = "";
$banco = "banco";

// Conectando ao banco de dados
$conn = mysql_connect($host, $usuario, $senha) or die (mysql_error());
// Selecionando o banco de dados
$db = mysql_select_db($banco, $conn) or die (mysql_error());
// Definindo o charset como utf8 para evitar problemas com acentuação
$charset = mysql_set_charset("utf8");

3. Exibindo as frases (index.php)

Em nosso arquivo principal vamos exibir as frases e já deixar no jeito os elementos para mais adiante desenvolver nosso código javascript:

<?php include ("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" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Sistema de votação simples com PHP/JQuery/AJAX</title>

</head>

<body>
<h1>Sistema de votação simples com PHP/JQuery/AJAX</h1>

<?php
// Selecionando todas as frases
$query = mysql_query("SELECT * FROM frases ORDER BY id DESC");
// Passando frase por frase
while ($frase = mysql_fetch_object($query)):
?>

<div class="frase" lang="<?php echo $frase->id; ?>">
    <div class="texto"><?php echo $frase->texto; ?></div>
    
    <img src="imagens/bom.png" alt="bom" />
    <span class="bom">
        (<span class="valor"><?php echo $frase->bom; ?></span>)
    </span>
    
    <img src="imagens/ruim.png" alt="ruim" />
    <span class="ruim">
        (<span class="valor"><?php echo $frase->ruim; ?></span>)
    </span>
    
    <div class="status"></div>
</div>

<?php endwhile; ?>
</body>
</html>

Mesmo parecendo simples para alguns, vou explicar o que é mais relevante no código:

Linha 1: Incluímos o arquivo de conexão;

Linha 15: Selecionamos todas as frases no banco de dados e ordenamos em ordem decrescente;

Linha 17: Criamos um loop que irá passar frase por frase; tudo o que está entre a Linha 19 e a Linha 35 será criado para cada frase;

Linha 20: Criamos uma DIV e atribuímos a propriedade LANG a ID da frase, para que mais adiante possamos recuperar esse ID com javascript;

Linha 21 a 35: Exibimos as demais informações da frases e também as imagens de bom e ruim;

Linha 26: Finalizamos o loop.

Resumindo, nós criamos uma DIV para cada frase; Essa DIV possui na propriedade LANG o ID da frase, portanto cada DIV representa uma frase, assim podemos manipular as frases facilmente com JQuery.

4. O JQuery (index.php)

Primeiramente vamos incluir o jquery.js:

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

Agora nós podemos manipular os facilmente elementos da página. Nosso código é o seguinte:

<script type="text/javascript">
$(function($) {
    // Quando clicando em uma imagem da div que tem CLASS = frase
    $("div.frase img").click(function() {
        // Recupera o ID da frase que está na propriedade LANG da DIV-PAI da imagem e que tem CLASS = frase
        var id = $(this).parent("div.frase").attr("lang");
        // Recupera o tipo (bom|ruim) que está na propriedade ALT da imagem clicada
        var tipo = $(this).attr("alt");
        // Seleciona o SPAN onde estão os votos
        var votos =  $("div[lang="+id+"] span."+tipo+" span.valor");
        // Seleciona a DIV onde serão colocadas as mensagens
        var status = $("div[lang="+id+"] div.status");
        
        // Mensagem de carregando
        status.html("<img src='imagens/loader.gif' alt='Carregando...' />");
        
        // Faz a requisição AJAX
        $.post("ajax/votar.php", {id: id, tipo: tipo}, function(resposta) {
            // Se houver uma mensagem na resposta, exibe a mensagem
            if (resposta) 
            {
                status.html(resposta);
            } 
            // Quando a resposta for FALSE 
            else 
            {
                // Incrementa mais um aos votos
                votos.html(parseInt(votos.html()) + 1);
                // Mensagem de sucesso
                status.html("Obrigado por votar!");
            }
        });

    }); 
});
</script>

Bom, vou tentar detalhar o máximo possível.

Linha 2: Iniciamos o código, ou seja, isso irá chamar as funções quando a página for carregada;

Linha 4: Quando clicando em uma imagem de uma DIV com class=”frase”, ou seja, quando o usuário clicar sobre as imagens bom ou ruim;

Linha 6: Recuperamos o ID da frase; como foi dito antes o ID está na propriedade LANG da DIV com class=”frase”. Como as imagens estão dentro dessa DIV utilizamos a função parent() para selecionar a DIV e depois utilizamos a função attr() para selecionar o atributo (propriedade) LANG e enfim temos o ID dessa frase;

Linha 8: Recuperamos o TIPO de voto (bom ou ruim); O tipo do voto está definido na propriedade ALT das imagens;

Linha 10: Selecionamos o SPAN onde está o número de votos atual; Selecionamos a partir do ID e do TIPO que já foram recuperados acima;

Linha 12: Selecionamos a DIV onde serão colocadas as mensagens;

Linha 15: Colocamos um loader na DIV status através da função html();

Linha 18: Fazemos a requisição AJAX (função JQuery.post()) com o arquivo ajax/votar.php que será criado adiante. Passamos, através do método post, o ID e o TIPO da frase para que possamos recuperar no arquivo PHP;

Linha 20 a 23: O arquivo PHP irá devolver uma resposta. Se essa resposta for uma mensagem, ou seja, verdadeiro (true), nós colocamos essa mensagem na DIV status;

Linha 26 a 30: Se essa resposta for falsa (false), quer dizer que não há nada de errado, portanto nós incrementamos os votos e colocamos no SPAN onde estão os votos. Depois colocamos a mensagem de sucesso na DIV status.

5. Nosso arquivo PHP (ajax/votar.php)

Bom, esse arquivo é o responsável por alterar os votos no banco de dados.

<?php
// Incluindo arquivo de conexão
include("../conn.php");

// Recuperando valores
$id = (int) $_POST["id"];
$tipo = addslashes($_POST["tipo"]);
$cookie = isset($_COOKIE["votado_".$id]) ? $_COOKIE["votado_".$id] : null; 

// Se o cookie ainda não foi setado
if (!isset($cookie))
{
    // Incrementa o voto da frase
    $query = mysql_query("UPDATE frases SET ".$tipo." = ".$tipo."+1 WHERE id = ".$id."");
    // Se for um sucesso a query
    if ($query) 
    {
        // Seta um cookie
        setcookie("votado_".$id."", true, time()+60*60*24*6004);
        // Retorna false, ou seja, sucesso
        echo false;
    }
    // Se houver erro na query 
    else 
    {
        echo "Problemas no servidor.";
    }
}
// Se já houver um cookie
else
{
    echo "Você já votou nessa frase.";
}
?>

Aqui nós incluímos o arquivo de conexão, recuperamos os valores passados através da requisição AJAX, verificamos se um cookie já foi criado para essa frase, caso não tenha sido criado, incrementamos os votos da frase no banco de dados e criamos um cookie para a frase, caso o cookie tenha sido criado, retorna uma mensagem de erro.

6. Concluindo

Meu objetivo foi tentar mostrar um pouco do poder e da flexibilidade de se trabalhar com JQuery. Fica muito simples manipular qualquer elemento da página e fazer uma requisição AJAX. E claro, apresentar um ideia de como fazer um sisteminha de votação com AJAX.

Download dos arquivos

Espero que vocês tenham entendido; Qualquer dúvida é só entrar em contato, ok?
Abraços.