Systém komentářů pomocí jQuery a Ajax.
Author: Dmitry Burobin
Dnes vytvoříme systém komentářů s automatickou kontrolou vstupních dat pomocí technologie Ajax a přidáváním nového komentáře s použitím jQuery bez znovunačtení stránky.
2) Lajkování neboli karma u komentářů.
3) Strankování.
Vytvoření tabulky a připojení k databázi.
Vytvoříme si tabulku comments, do které budeme ukládat: identifikátor komentáře ( id ), identifikátor rodičovského komentáře ( parent_id ), jméno ( name ),
text komentáře ( text ) a datum přidání komentáře ( date ).
CREATE TABLE `comments` ( `id` INT ( 5 ) NOT NULL AUTO_INCREMENT, `parent_id` INT ( 5 ) NOT NULL, `name` VARCHAR ( 255 ) NOT NULL, `komentar` TEXT, `date` DATETIME, PRIMARY KEY(`id`) )ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci
Taktéž si vytvořte soubor db.php, pro připojení k databázi.
<?php
$DBSERVER
= 'localhost'; //server, který bude použít pro navázáníspojení s DB
$DBUSER = 'root'; //Váš mysql login, nejspíš je stejný jako u mě pro localhost, tudiž root
$DBPASS = '****'; //heslo, které jste zadaval při instalaci MySQL
$DB = 'test'; //databáze, s kterou budeme pracovat
//navazení spojení pomoci mysql_connect
$link = mysql_connect($DBSERVER, $DBUSER, $DBPASS) or die("Could not connect: " . mysql_error());
//vybírame databázi
mysql_select_db($DB, $link) or die ('Can\'t use test : ' . mysql_error());
//řekněme MySQL, že všechná data jsou ve formatu UTF-8
mysql_query("SET NAMES UTF8");
?>
index.php
Hlavní stránka bude obsahovat formulář pro přidávání komentářů s polem pro jméno, zprávu a skryté pole, do kterého budeme ukálát identifikátor rodičovského
komentáře, pokud někdo bude odpovídat na nějaký komenář. Soubor index.php vypadá takto:
<?php
/*Soubor pro vybírání komentářů z databáze*/
require_once 'comment.php';
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs" lang="cs">
<head>
<title>Systém komentářů.</title>
<meta charset="utf-8" >
<link rel="stylesheet" href="style.css"> <!-- soubor se styly -->
<script src="jquery-1.7.1.min.js"></script> <!-- připojení jquery -->
<script src="comment.js"></script> <!-- funkce potřebné pro přidávání komentářů -->
</head>
<body>
<ul id="commentWrapper">
<?php
/*Zde v proměnné $comments jsou komentáře*/
echo $comments;
?>
<!-- formulář pro přidávání komentářů -->
</ul>
<div id="commentBox">
<input class="validate" type="text" name="name" >
<input id="parent" type="hidden" name="parent_id" value="">
<div class="commentText">
<textarea name="text"></textarea>
</div>
<button>Přidat</button><img class="loader" src="loader.gif">
</div>
</body>
</html>
Styly a knihovna jQuery
Pro správné fungování potřebujeme připojit knihovnu jQuery. Tu buď stáhnete z oficiálního webu nebo z archivu s tímto článkem.
Pak, aby komentáře líp vypadali přidáme styly, nic složitého v nich není, proto je nebudu popisovat:
body
{
margin:0;
padding:0;
}
ul, li
{
list-style-type:none;
}
.loader
{
display:none;
}
#commentBox
{
width:400px;
padding:10px;
}
#commentBox input
{
width:250px;
height:25px;
padding: 0 5px;
margin:5px;
border: solid 1px #ccc;
background:#f1f1f1 url(bg_input.png) no-repeat;
font: 400 12pt/14pt Ume Gothic O5;
}
#commentBox textarea
{
width:250px;
height:100px;
margin: 5px;
padding: 5px;
border: solid 1px #ccc;
background:#f1f1f1 url(bg_koment.png) no-repeat;
font: 400 12pt/14pt Ume Gothic O5;
}
#commentBox button
{
height:30px;
width:85px;
margin-left: 183px;
margin-top:0px;
font:700 12pt/14pt Ume Gothic O5;
}
#commentWrap
{
width:350px;
padding:10px;
padding-bottom:3px;
margin:10px;
border: 1px solid #ccc;
border-radius:10px;
background:#f7f7f7;
}
#commentWrap .komentar
{
padding:5px;
padding-left:0px;
border-top:1px solid #ccc;
margin-bottom:10px;
font:400 12pt/14pt Times New Roman;
}
#commentWrap .replay
{
margin-left:270px;
font:700 10pt/12pt Ume Gothic O5;
}
#commentWrap a
{
text-decoration:none;
}
#commentWrap .commentName
{
font:700 10pt/12pt Ume Gothic O5;
}
#commentWrap .commentDate
{
font:400 11pt/13pt Times New Roman;
}
.repName
{
font:400 12pt/14pt Times New Roman;
font-style:italic;
}
.repText
{
font:700 10pt/12pt Ume Gothic O5;
}
.repDate
{
font:400 9pt/11pt Times New Roman;
font-style:italic;
}
comment.php
Tento soubor je určen pro vybírání dat z databáze a vkládání těchto dat do šablony.
<?php
// Vložíme soubor s připojením k databázi. ( musí se nacházet ve stejné složce )
require_once 'db.php';
// Vybereme komentáře z databáze
$query = mysql_query("
SELECT `id`,`parent_id`,`name`,`komentar`,
DATE_FORMAT(date, '%d %M %Y %H:%i') as date_add
FROM `comments` ORDER BY `id` ASC
");
// Pokud při vykonání příkazu nastané chyba vypišeme ji
if(!$query) { echo mysql_error() . " - " . mysql_errno(); }
else {
// Jinak pomocí cyklusu projdeme všechny záznamy v tabulce
while($result = mysql_fetch_assoc($query))
{
// a uložíme je do pole $data
$data[$result['id']] = $result;
}
// Funkce pro vkládání dat ( komentářů ) do šablony
function commentsToTemplate($comment)
{
// $comment - pole komentáře - id, parent_id, name, text, date
// Zapneme bufferování výstupu, aby šablona nebyla zobrazená v místě volání funkce
ob_start();
// Připojíme šablonu comment_template.php, do které vložíme data z pole $comment
require_once 'comment_template.php';
// Získáváme obsah bufferu jako řetězec
$comments_string = ob_get_contents();
// Vymažeme všechno z bufferu
ob_end_clean();
// Vrácíme komentář jako řetězec
return $comments_string;
}
// Funkce pro zpracování pole $data, které
// bude rozděleno do jednotlivých komentářů a odesláno funkci
// commentsToTemplate
function commentsString($data)
{
foreach($data as $w)
{
$string .= commentsToTemplate($w);
}
return $string;
}
// proměnná $comments obsahuje naše komentáře, které zobrazujeme na hlavní stránce
$comments = commentsString($data);
// vynulujeme proměnnou $data
$data = null;
}
?>
comment_template.php
Toto je vlastně šablona jednotlivého komentáře.
<?php
// Do této šablony se načítají data z pole $data, která jsou odesláná funkci commentsToTemplate
echo '<li id="comment'.$comment['id'].'">
<div id="commentWrap">';
// Pokud existuje parent_id, pak zobrazíme, že se jedna o odpověď
if($comment['parent_id']!=0)
{
// Vybereme z DB jméno a datum rodičovského komentáře
$q = mysql_query("SELECT `name`, DATE_FORMAT(date, '%d %M %Y %H:%i') as date_add FROM `comments_my` WHERE `id`='".$comment['parent_id']."'");
$r = mysql_fetch_assoc($q);
echo '<span class="repText">Odpověď na komentář</span> <span class="repName">
'.$r['name'].'
</span> <span class="repText">from</span> <span class="repDate">
'.$r['date_add'].'
</span><br>';
}
// Zobrazíme jméno a datum přidání
echo '<span class="commentName">'.$comment['name'].'</span> - <span class="commentDate">'.$comment['date_add'].'</span>
<div class="komentar">
<!--Zobrazíme text komentáře-->
'.$comment['komentar'].'
</div>
<!--Pokud zmačkneme na tento odkaz, pak se do skrýteho pole s názvem parent_id přidá
identifikátor tohoto komentáře.
Použil jsem zde JS událost onClick, tzn. pokud je tlačítko zmačknuté, pak najdi prvek s
id parent ( což je skrýte pole parent_id ) a do hodnoty přidej id komentáře, na který chcete odpovědět-->
<a class="replay" href="javascript:;"
onClick="document.getElementById(\'parent\').value='.$comment['id'].';">Odpovědět</a>
</div>
</li>';
?>
comment.js
Tento soubor je určen pro odesílaní dat na server a přidávání do databáze
$(document).ready(function(){
// Objekt commentBox bude obsahovat data pro odesílání na server
var commentBox = {};
// Po kliknutí na tlačítko přidat
$('#commentBox button').live('click',function(){
// Do objektu commentBox bude přidána hodnota skrýteho pole input s názvem parent_id,
// které obsahuje id rodičovského komentáře a pokud je prázdné tak bude 0, což znamená, že
// se jedná o nový komentář bez reakci na něj ( toto se bude ověřovat až odešleme data na server ).
commentBox.parent_id = $('#commentBox').find("input[name='parent_id']").val();
// Taktéž přidáme do objektu commentBox hodnotu pole name a zprávu
commentBox.name = $('#commentBox').find("input[name='name']").val();
commentBox.text = $('#commentBox').find("textarea").val();
// Abyste to lépe pochopili syntaxe toho, jak přidáváme hodnoty do objektu je:
// Objekt.název_proměnné = hledáme input nebo textarea.hodnota pole
// Funkce pro odesílání dat na server
sendData();
});
function sendData()
{
// Najdeme tlačítko schováme jej a zobrazíme loader ( ten si můžete stáhnout z archivu )
$('#commentBox').find('button').hide().next().show();
// Odešleme data metodou post na server
$.post(
// Soubor, ve kterém se provádí ověřování dat a přidávání komentářů
"addkoment.php",
// Objekt s proměnnými (parent_id, name a text)
commentBox,
function(data){
// Pokud jsou nějaka data, to znamená, že nastala chyba
if(data)
{
// Převedeme tento řetězec JSON do objektu JS
data = $.parseJSON(data);
// Vytvoříme proměnnou errors, která bude obsahovat název chyby
var errors = '';
// Použijeme cyklus pro zobrazení všech chyb najednou.
// Použil jsem tuto konstrukci, protože nejprvé jsem zobrazoval všechny chyby, ale
// nakonec jsem to změnil a teď se bude zobrazovat jenom jedna konkretní chyba
// Kdybyste chtěli zobrazit všechny chyby tak použijte konstrukci
// errors += val+'\n'; - každá chyba se zobrazí na samostatném řádku.
// i - obsahuje název chybného pole a val - popis chyby
$.each(data, function(i, val)
{
errors += i;
});
// Uložil jsem do proměnné errors jenom název chybného pole a
// cyklusem switch procházim všechny varianty a přidávam červený rámeček
// pokud pole je prázdné nebo jestli komentář nebyl přidan tak zobrazim hlášení
switch (errors)
{
case 'name':
$('#commentBox').find("input[name='name']").css('border','2px solid red');
break
case 'text':
$('#commentBox').find("textarea").css('border','2px solid red');
break
case 'not_add':
alert('Komentář nebyl přidan.')
break
default:
alert('Něco je špatně')
}
// Najdeme loader ( ten si můžete stáhnout z archivu ) schováme jej a zobrazíme tlačítko přidat
$('#commentBox').find('button').show().next().hide();
// Jinak, pokud žadná chyba nenastala, tak voláme funkci addComment, která zobrazí
// komentář bez znovunačtení stránky a vynuluje hodnoty vstupních poli
} else {
addComment();
}
}
)
}
function addComment()
{
// Na konec prvků s id commentWrapper ( což je ul ) přidame tag <li></li>,
// ve kterém se bude nacházet nový komentář
$("#commentWrapper").append('<li></li>');
// Najdeme poslední tag <li>, který jsme teď vytvořili a
// načteme do něj poslední komentář
$("#commentWrapper li:last").load('new_comment.php');
// Najdeme loader ( ten si můžete stáhnout z archivu ) schováme jej a zobrazíme tlačítko přidat
$('#commentBox').find('button').show().next().hide();
// Vynulujeme hodnoty vstupních poli
$('#commentBox input').val('');
$('#commentBox textarea').val('');
}
});
addkoment.php
Tento skript zpracovává data poslána na server pro zpracování.
<?php
// Ověříme, zda se jedna o odeslána POST data nebo si člověk jen tak otevřel tuto stránku
if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
// Pokud ano, pomocí funkci sleep přidame efekt zpoždění, abyste
// viděl loader, jinak, protože pracujeme na lokálním serveru
// se ten loader hned schová
sleep(2);
// Ověříme vstupní data
// Pokud je pole name nebo textové pole prázdné do pole $error uložíme text chyby
// ukončíme skript a odešleme tuto chybu v JSON formátu
if(!isset($_POST['name']) OR empty($_POST['name']))
{
$error['name'] = "Zadejte jméno.";
exit(json_encode($error));
} else {
$name = htmlspecialchars(stripslashes(trim($_POST['name'])));
}
if(!isset($_POST['text']) OR empty($_POST['text']))
{
$error['text'] = "Zadejte zprávu.";
exit(json_encode($error));
} else {
$text = stripslashes(htmlspecialchars(trim($_POST['text'])));
}
// V tomto případě, když parent_id je prázdné pole tak mu přiřadime hodnotu 0
// to znamená, že se jedná o nový komentář, který není odpovědí na něčí jiný
if(!isset($_POST['parent_id']) OR empty($_POST['parent_id']))
{
$parent_id = 0;
} else {
$parent_id = stripslashes(htmlspecialchars(trim($_POST['parent_id'])));
}
// Vložíme soubor s připojením k databázi. ( musí se nacházet ve stejné složce )
require_once 'db.php';
// Přidame komentář do databáze a vrátíme false, tzn.
// že chyba nenastala a komentář byl přidán.
$q = mysql_query("
INSERT INTO `comments`(`parent_id`,`name`,`komentar`,`date`)
VALUES('".$parent_id."','".$name."','".$text."', NOW())
");
if(!$q) { $error['not_add'] = "Komentář nebyl přidan."; exit(json_encode($error));}
else { exit(false); }
}
?>
new_comment.php
V tomto souboru vybírame poslední komentář, abysme ho následně zobrazili po úspěšnem ověření vstupních dat.
<?php
// Vložíme soubor s připojením k databázi. ( musí se nacházet ve stejné složce )
require_once 'db.php';
// Vybereme maximální ( poslední přidáný ) id
$max = mysql_query("SELECT MAX(`id`) FROM `comments_my`");
// Pak vybereme všechny související údaje s tímto identifikátorem
$query = mysql_query("
SELECT `parent_id`,`name`,`komentar`,
DATE_FORMAT(date, '%d %M %Y %H:%i') as date_add
FROM `comments_my` WHERE `id` = '".mysql_result($max,0)."'
");
$comment = mysql_fetch_assoc($query);
// A stejně, jak jsme zobrazovali komentáře před tím, zobrazíme poslední přidáný
echo '<li id="comment'.mysql_result($max,0).'">
<div id="commentWrap">';
if($comment['parent_id']!=0)
{
$q = mysql_query("SELECT `name`, DATE_FORMAT(date, '%d %M %Y %H:%i') as date_add FROM `comments_my` WHERE `id`='".$comment['parent_id']."'");
$r = mysql_fetch_assoc($q);
echo '<span class="repText">Odpověď na komentář</span> <span class="repName">
'.$r['name'].'
</span> <span class="repText">from</span> <span class="repDate">
'.$r['date_add'].'
</span><br>';
}
echo '<span class="commentName">'.$comment['name'].'</span> - <span class="commentDate">'.$comment['date_add'].'</span>
<div class="komentar">
'.$comment['komentar'].'
</div>
<a class="replay" href="javascript:;"
onClick="document.getElementById(\'parent\').value='.mysql_result($max,0).';">Odpovědět</a>
</div>
</li>';
?>
Závěr
Probrali jsme, jak můžeme zpracovávát formuláře bez znovunačtení stránky. Doufám, že se Vám tento článek líbil a byl pro Vás přínosný.