Thỏa theo yêu cầu của bạn hnk8 và chắc hẵn rất nhiều bạn khác cũng cùng chung thắc mắc về vấn đề tạo chém gió giống như blog này. Hôm nay, tớ sẽ hướng dẫn chi tiết cách tạo shoutbox dùng jQuery (AJAX, JSON) , PHP và MySQL.

Cũng như các bài hướng dẫn khác, để hiểu bài viết này bạn cần phải nắm bắt được một vài điều đơn giản sau đây:
Các bạn hãy tạo cho mình một cấu trúc project giống như sau để dễ dàng theo dõi bài viết: download image bugy _ 
www/
shoutbox/
css/
general.css
images/
busy.gif
js/
jquery.shoutbox.js
php/
fns.php
index.html
Mở file index.html và nhập vào đoạn mã dưới đây:
<!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>
<title>DEMO: Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link type="text/css" rel="stylesheet" href="css/general.css" />
</head>
<body>
<div id="wrapper">
<h1>kenphan.info</h1>
<h2>Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox</h2>
<div id="container">
<div id="shoutboxList">
<div id="shoutboxListMsg">
<ul>
<li>...</li>
<li>...</li>
</ul>
</div>
<div id="shoutboxBusy"></div>
</div>
<div id="shouboxCtrls">
<ul class="clearfix">
<li><a href="javascript:void(0);" id="shoutboxPrev">« prev</a></li>
<li> ..... </li>
<li><a href="javascript:void(0);" id="shoutboxNext">next »</a></li>
<li class="right"><a href="javascript:void(0);" id="shoutboxRefresh">÷ refresh</a></li>
</ul>
</div>
<div id="shoutboxForm">
<form action="" method="post" name="shoutbox" id="shoutbox">
<dl>
<dt><input type="text" name="author" id="author" onfocus="if(this.value=='your name') this.value='';" onblur="if(this.value=='') this.value='your name';" value="your name" alt="Name" /></dt>
<dd><input type="text" name="message" id="message" onfocus="if(this.value=='your message') this.value='';" onblur="if(this.value=='') this.value='your message';" value="your message" alt="Message" /></dd>
</dl>
<div id="submitWrap"><input type="submit" name="shoutboxSubmit" value="" /></div>
</form>
</div>
</div>
</div>
</body>
</html>
Mở file general.css trong thư mục css và nhập vào đoạn mã sau:
@CHARSET "UTF-8";
/******* GENERAL RESET *******/
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
font, img, ins, kbd, q, s, samp, small, strike, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody,
tfoot, thead, tr, th, td {
border:0pt none;
font-family:inherit;
font-size: 100%;
font-style:inherit;
font-weight:inherit;
margin:0pt;
padding:0pt;
vertical-align:baseline;
}
input {
margin:0;padding:0;
}
body{
background-color: #e1e1e1;
line-height:14px;
margin:0pt;
cursor
efault;
}
body,input {
font-size: 12px;
font-family: Tahoma, Arial, Verdana, Helvetica, sans-serif;
}
html,body{
height:100%;
text-align: center;
}
a {
text-decoration: none;
color:#666;
}
a:hover {
color:#000;
}
#wrapper {
margin:0px auto;
margin-top:40px;
width:700px;
text-align:left;
}
h1 {
font-size: 30px;
line-height: normal;
font-weight: bold;
margin-bottom:3px;
}
h2 {
line-height: normal;
font-size:13px;
font-weight: normal;
}
#container {
margin-top:10px;
}
#shoutboxList {
width:100%;
position: relative;
background-color:#fff;
}
#shoutboxList #shoutboxBusy {
top:5px;
left:-20px;
width:16px;
height:16px;
display: none;
position: absolute;
background: #fff url(../images/busy.gif) no-repeat 98% 50%;
}
#shoutboxList ul {
list-style: none;
}
#shoutboxList ul li {
padding:8px 5px;
height:1%;
margin-bottom: 1px;
background-color: #ededed;
}
#shoutboxList ul li .createdDate {
color:#999;
font-size:11px;
}
#shoutboxList ul li .authorName {
font-weight: bold;
}
#shoutboxList ul li .message {
}
#shoutboxList ul li.even {
background-color: #e5e5e5;
}
#shouboxCtrls {
padding:5px;
margin:5px 0px;
font-size: 11px;
background-color:#f9f9f9;
}
#shouboxCtrls ul {
list-style: none;
}
#shouboxCtrls ul li {
float: left;
color: #666;
margin-right:10px;
}
#shouboxCtrls ul li.right {
float: right;
margin-right:0px;
}
#shoutboxForm {
}
#shoutboxForm dl {
}
#shoutboxForm dt {
float: left;
}
#shoutboxForm dd {
margin-left:165px;
}
* html #shoutboxForm dd {
margin-left: 150px;
}
#shoutboxForm dl input {
border:none;
padding: 5px;
outline: none;
background-color: #fff;
}
#shoutboxForm dl input#author {
width:150px;
}
#shoutboxForm dl input#message {
width:525px;
}
#shoutboxForm #submitWrap {
position: absolute;
top:-999999px;
left:-999999px;
}
/* CLEAR FIX LAYOUT */
* html > body .clearfix {
width: 100%;
display: block;
}
* html .clearfix {
height: 1%; /* IE5-6 */
}
.clearfix {
display: inline-block; /* IE7xhtml*/
}
html[xmlns] .clearfix {
display: block; /* O */
}
.clearfix:after {
clear: both;
content: "."; /* FF, O, etc. */
display: block;
height: 0;
line-height: 0;
visibility: hidden;
}
Vì đây không phải là bài viết hướng dẫn CSS cho nên lúc này các bạn chỉ việc copy và paste. Chạy thử file HTML của bạn và nếu nó giống như hình dưới này thì mọi việc đều diễn ra tốt đẹp.

Tiếp tục bước tiếp theo, chúng ta sẽ tạo DB cho ứng dụng shoutbox. Tớ sẽ tạo 1 table gọi là test_shoutbox và 1 bảng là shoutbox: Xem mã ở dưới:
CREATE TABLE `shoutbox` ( `id` int(11) NOT NULL auto_increment, `author` varchar(100) NOT NULL, `message` text NOT NULL, `created_date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `IP` varchar(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=22 ;
Thêm thông tin cho shoutbox:
INSERT INTO `shoutbox` VALUES (17, 'Admin', 'Support dynamic process phases ', '2010-04-07 15:50:03', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (16, 'Khoa', 'Administration Intern, Produktprozesse (30)', '2010-04-07 15:49:12', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (7, 'Phương', 'PLease update it for all popups in the whole system. Also make it as clear as possible.', '2010-04-07 15:24:15', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (8, 'Tài', 'We have three different kinds of addresses in the home delivery service:', '2010-04-07 15:25:13', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (9, 'Quân', 'The Customer User Administration have no detailed display in the header section. Please check it in the whole tool. ', '2010-04-07 15:26:11', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (10, 'Hiển', 'OK, the title of the screen is displayed. Please add also before the action (edit the layout) also for which cimpany you are chanfing.', '2010-04-07 15:27:02', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (11, 'Phong', 'assigned_to changed from sib_quan.tran to sib_phuong.phan ', '2010-04-07 15:27:54', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (12, 'Đông', 'The title of the popups should always display also the navigation to give an idea to the user, where exactly he is and the data of which company he is changing.', '2010-04-07 15:29:15', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (13, 'Hái', 'For example: Go! Expess & Logistics (Schweiz) AG >> Add Company User', '2010-04-07 15:29:53', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (15, 'Vương', 'Watch our tutorial video for the Tickets Tool', '2010-04-07 15:33:21', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (18, 'Tư', 'description changed from Administration Intern, Prod... to Administration Intern, Prod... ', '2010-04-07 15:50:42', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (19, 'Vũ', 'Administration Intern, Produktprozesse', '2010-04-07 15:52:40', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (20, 'Allbory', '"If you wish to break the each() loop at a particular iteration you can do so by making your function return false. Returning non-false is the same as a continue statement in a for loop, it will skip "', '2010-04-07 17:44:22', '127.0.0.1'); INSERT INTO `shoutbox` VALUES (21, 'google', ' Why is it that the $.each utility method doesn''t exit the loop on ... in the the jQuery code', '2010-04-07 17:45:06', '127.0.0.1');
Ở bài viết này không dừng lại ở vấn đề đơn giản là viết AJAX để lấy dữ liệu từ PHP, mà tớ sẽ hướng dẫn cách viết một class database, tuy nó chỉ là simply nhưng bạn có thể cải tiến nó để tiện lợi trong việc coding và giảm thời gian truy vấn một cách nhanh chóng và tối ưu nhất. Tiếp tục tạo một đối tượng mysql dùng để truy xuất Cơ sở Dữ liệu (CSDL). Mở file fns.php trong thư mục php và làm theo hướng dẫn:
class mysql
{
}
Thêm 1 vài thuộc tính như sau:
public $dbhost = 'localhost'; // host public $dbname = 'test_shoutbox'; // database name public $dbuser = 'root'; // database username public $dbpass = 'root'; // database password protected $conn; // conect database protected $connDB; // dabase selected
Trong class này, tớ khai báo bốn thuộc tính dùng để kết nối Database. Tiếp tục viết một phương thức dùng để kết nối CSDL:
function connectDB()
{
$this->conn = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)
or die('Could not connect: ' . mysql_error());
$this->connDB = mysql_select_db($this->dbname);
@mysql_query('SET time_zone = "Asia/Saigon"'); // set time zone
@mysql_query("set names 'utf8'"); // set unicode utf8
}
Tạo một phương thức dùng để đóng kết nối CSDL:
function closeDb()
{
mysql_close($this->conn);
}
Tạo phương thức mysql_query, thuộc tính này có một tham số đầu vào, tham số này là câu lệnh truy vấn MySQL:
function query($sql)
{
$query = mysql_query($sql)
or die('Invalid query: ' . mysql_error());
return $query;
}
Tạo phương thức dùng để lấy tất cả dữ liệu, thuộc tính này nhận vào một query MySQL:
function fetchAll($result)
{
while ($rows = mysql_fetch_assoc($result)) {
$results[] = $rows;
}
mysql_free_result($result); // free memory
return $results;
}
Tạo phương thức để escape dữ liệu:
function escape ($value)
{
if( get_magic_quotes_gpc() ) {
$value = stripslashes( $value );
}
if(function_exists( "mysql_real_escape_string" ) ) { // mysql_real_escape_string is exist
$value = @mysql_real_escape_string( $value );
} else { // or
$value = addslashes( $value );
}
return $value;
}
Phương thức dùng để insert dữ liệu, tham số truyền vào: @param1: bảng dữ liệu, @param2: dữ liệu (type: Array):
function insert($table, $data)
{
$q="INSERT INTO `".$table."` ";
$v=''; $n='';
foreach($data as $key => $val) {
$n.="`$key`, ";
if(strtolower($val)=='null') {
$v.="NULL, ";
}
elseif(strtolower($val)=='now()') {
$v.="NOW(), ";
}
else {
$v.= "'".$this->escape($val)."', ";
}
}
$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";
if($this->query($q)) {
return @mysql_insert_id();
}
else return false;
}
OK, vì bài viết chỉ hướng dẫn vừa đủ cho nên tớ sẽ không viết thêm các phương thức update, delete,... các phương thức đó bạn hãy tự viết nhé
Tổng duyệt lại thì lớp mysql của chúng ta sẽ như sau:
class mysql
{
public $dbhost = 'localhost'; // host
public $dbname = 'test_shoutbox'; // database name
public $dbuser = 'root'; // database username
public $dbpass = 'root'; // database password
protected $conn; // conect database
protected $connDB; // dabase selected
function connectDB()
{
$this->conn = mysql_connect($this->dbhost, $this->dbuser, $this->dbpass)
or die('Could not connect: ' . mysql_error());
$this->connDB = mysql_select_db($this->dbname);
@mysql_query('SET time_zone = "Asia/Saigon"'); // set time zone
@mysql_query("set names 'utf8'"); // set unicode utf8
}
function closeDb()
{
mysql_close($this->conn);
}
function query($sql)
{
$query = mysql_query($sql)
or die('Invalid query: ' . mysql_error());
return $query;
}
function fetchAll($result)
{
while ($rows = mysql_fetch_assoc($result)) {
$results[] = $rows;
}
mysql_free_result($result); // free memory
return $results;
}
function escape ($value)
{
if( get_magic_quotes_gpc() ) {
$value = stripslashes( $value );
}
if(function_exists( "mysql_real_escape_string" ) ) { // mysql_real_escape_string is exist
$value = @mysql_real_escape_string( $value );
} else { // or
$value = addslashes( $value );
}
return $value;
}
function insert($table, $data)
{
$q="INSERT INTO `".$table."` ";
$v=''; $n='';
foreach($data as $key => $val) {
$n.="`$key`, ";
if(strtolower($val)=='null') {
$v.="NULL, ";
}
elseif(strtolower($val)=='now()') {
$v.="NOW(), ";
}
else {
$v.= "'".$this->escape($val)."', ";
}
}
$q .= "(". rtrim($n, ', ') .") VALUES (". rtrim($v, ', ') .");";
if($this->query($q)) {
return @mysql_insert_id();
}
else return false;
}
}
Mở file index.html, embed thư viện jQuery và jQuery Shoutbox vào:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="js/jquery.shoutbox.js"></script>
Mở file jquery.shoutbox.js trong thư mục js và tiếp tục. Bước đầu tiên, chúng ta sẽ tạo ra một vài biến toàn cục dùng để xử lý trong shoutbox:
var _objs = {}, _data, _rows = 5, _start = 0;
_objs: lưu lại tất cả các DOM Element chúng ta sẽ sử dụng.
_data: dữ liệu database trả về sẽ được lưu ở biến này.
_rows: số dòng sẽ hiện trên một trang.
_start: trang đầu tiên được tải.
Khởi động jQuery 
$(document).ready(function(){
// code here
});
Tiếp tục, truyền tất cả các DOM Element sẽ được xử lý vào biến toàn cục _objs
var _objs = {}, _data, _rows = 5, _start = 0;
jQuery(document).ready(function(){
_objs = {
prev: jQuery('#shoutboxPrev'),
next: jQuery('#shoutboxNext'),
refr: jQuery('#shoutboxRefresh'),
form: jQuery('#shoutbox'),
busy: jQuery('#shoutboxBusy'),
list: jQuery('#shoutboxListMsg'),
iaut: jQuery('#author'),
imsg: jQuery('#message')
}
});
Ở đây, chúng ta có các DOM Element sau:
_objs.prev: liên kết đến trang trước đó.
_objs.next: liên kết đến trang sau.
_objs.refr: refresh lại dữ liệu.
_objs.form: form post dữ liệu.
_objs.busy: hình loading.
_objs.list: danh sách tất cả các message.
_objs.iaut: form input tác giả.
_objs.imsg: form input message.
Tiếp tục tạo gọi đối tượng dùng để khởi đông shoutbox, hàm này sẽ là trung tâm điều khiển shoutbox của chúng ta:
var _objs = {}, _data, _rows = 5, _start = 0;
jQuery(document).ready(function(){
_objs = {
prev: jQuery('#shoutboxPrev'),
next: jQuery('#shoutboxNext'),
refr: jQuery('#shoutboxRefresh'),
form: jQuery('#shoutbox'),
busy: jQuery('#shoutboxBusy'),
list: jQuery('#shoutboxListMsg'),
iaut: jQuery('#author'),
imsg: jQuery('#message')
}
// initialize shoutbox
jQuery.ctrlSBox();
});
Đối tượng jQuery.ctrlSBox(), nhận vào hai tham số, một là dữ liệu sẽ được gởi đến PHP, hai là hàm callback, hàm này sẽ được thực thi khi AJAX được tải thành công.
/*
* load ajax get data response and control heart
* @values: data request
* @fn: function callback
*/
jQuery.ctrlSBox = function(values, fn){
var url = _objs.form.attr('action');
if(typeof values == undefined) {
values = {};
}
jQuery.busySBox.call(_objs.busy);
jQuery.post(url, values, function(data){
if(typeof fn == 'function') {
fn(data);
} else {
_data = data; jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
jQuery.busySBox.call(_objs.busy, true);
}, 'json');
}
Giải thích:
Khai báo biến url, biến này sẽ có giá trị được lấy từ attribute action của form shoutbox. Kiểm tra nếu tham số values đầu tiên được gởi vào là undefined thì sẽ cho values là một đối tượng. Tiếp theo là gọi đối tượng busySBox(), đối tượng này dùng để hiện hình loading. Dùng jQuery AJAX jQuery.post() để gọi AJAX, khi dữ liệu được trả về, kiểm tra nếu loại (typeof) của tham số thứ hai là function thì sẽ gọi cái function đó, ngược lại thì dữ liệu trả về sẽ được tham chiếu cho biến toàn cục _data, gọi đối tượng jQuery.displaySBox(), đối tượng này append HTML vào nơi cần hiển thị, jQuery.htmlSBox() sẽ xử lý và trả về dữ liệu HTML. Ẩn loading.
/*
* show/hide busy image
* @close: if true is hide busy image
*/
jQuery.busySBox = function(close){
if(close == true) {
return jQuery(this).hide();
}
return jQuery(this).show();
}
/*
* display HTML data to DOM
* @data: html shoutbox list after processing HTML
*/
jQuery.displaySBox = function(data) {
jQuery(this).html(data).find('li:even').addClass('even');
}
/*
* Data processing returns html
* @data: type JSON
*/
jQuery.htmlSBox = function(){
if(typeof _data == undefined) {
alert("line 97 has bug !"); return false;
}
var html = ['<ul>'];
jQuery.each(_data.items, function(i, item) {
if(i < _start + _rows && i >= _start) {
html.push('<li>');
html.push('<span class="createdDate">' + item.created_date + '</span> ');
html.push('<span class="authorName">' + item.author+ '</span> ');
html.push('<span class="message">' + item.message+ '</span>');
html.push('</li>');
}
}); html.push('</ul>');
return html.join('');
}
Giải thích đối tượng jQuery.htmlSBox(), đầu tiên, nó sẽ kiểm tra nếu _data đã được khai báo nhưng chưa có dữ liệu thì sẽ thông báo lỗi (trường hợp này rất ít xảy ra). Như ở bài viết 9 tuyệt chiêu JavaScript bạn cần biết, tớ có phân tích về undefined, null, và nối chuỗi, ở đối tượng này, bạn sẽ thấy tớ không dùng phép nối chuỗi += operator mà dùng push() và join() để nối các chuỗi lại với nhau. Việc này sẽ giúp js chạy nhanh hơn cách thông thường. 
Đối với PHP, mở file fns.php và thêm vào như sau:
$sb = new mysql();
$sb->connectDB(); // connect db
if(isset($_POST['author']) && isset($_POST['message'])) {
if($_POST['author'] == 'your name' || $_POST['author'] == "") {
die('{ "auth": false, "message": "Vui lòng nhập tên của bạn !" }');
}
if($_POST['message'] == 'your message' || $_POST['message'] == "") {
die('{ "auth": false, "message": "Vui lòng nhập nội dung của bạn !" }');
}
$data = array(
'author' => $_POST['author'],
'message' => $_POST['message'],
'created_date' => 'NOW()',
'IP' => $_SERVER['REMOTE_ADDR']
);
$sb->insert('shoutbox', $data);
}
$sql = $sb->query("
SELECT *, DATE_FORMAT(created_date, '%H:%i %d/%m/%y') AS created_date
FROM shoutbox ORDER BY id DESC
");
$rows = $sb->fetchAll($sql); // fetch all records
$sb->closeDb(); // close connect
echo '{ "auth": true, "items": '. json_encode($rows) .' }';
Giải thích:
1. Khởi tạo đối tượng mysql
2. Mở kết nối CSDL
3. Kiểm tra nếu trang hiện đang được POST và có dữ liệu thì sẽ xử lý ...
4. Kiểm tra POST author
5 - 7. Nếu không thỏa thì thông báo, dữ liệu trả về là JSON
8 - 10. Kiểm tra POST message
11 - 16. Nếu không có gì thì sẽ insert dữ liệu vào CSDL
18 - 22: Query MySQL command và lấy tất cả dữ liệu
23: Đóng kết nối CSDL
24: Hiển thị dữ liệu
Tiếp tục mở jquery.shoutbox.js và thêm xử lý next, prev và refresh:
// event previous
_objs.prev.click(function(){
if(_start <= _data.items.length && _start > 0) {
_start -= _rows;
jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
});
// event next
_objs.next.click(function(){
if(_start >= 0 && _data.items.length > _start + _rows) {
_start += _rows;
jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
});
// event refresh
_objs.refr.click(function(){ _start = 0; jQuery.ctrlSBox(); });
Các điều kiện đưa ra thì bạn đã thấy như ở trên, rất khó để giải thích nó
, các bạn tự hiểu đi nhé ... nếu không hiểu thì viết cảm nhận mình sẽ giải thích rõ ràng hơn. Tiếp tục là sự kiện post dữ liệu:
// event submit
_objs.form.submit(function(){
var self = jQuery(this);
jQuery.ctrlSBox(self.serialize(), function(data){
if(data.auth == true) {
_start = 0; _objs.imsg.val(''); _objs.iaut.val('').focus();
_data = data; jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
} else {
jQuery.jGrowl(data.message);
}
});
return false;
});
var _objs = {}, _data, _rows = 5, _start = 0;
jQuery(document).ready(function(){
_objs = {
prev: jQuery('#shoutboxPrev'),
next: jQuery('#shoutboxNext'),
refr: jQuery('#shoutboxRefresh'),
form: jQuery('#shoutbox'),
busy: jQuery('#shoutboxBusy'),
list: jQuery('#shoutboxListMsg'),
iaut: jQuery('#author'),
imsg: jQuery('#message')
}
// initialize shoutbox
jQuery.ctrlSBox();
// event previous
_objs.prev.click(function(){
if(_start <= _data.items.length && _start > 0) {
_start -= _rows;
jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
});
// event next
_objs.next.click(function(){
if(_start >= 0 && _data.items.length > _start + _rows) {
_start += _rows;
jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
});
// event refresh
_objs.refr.click(function(){ _start = 0; jQuery.ctrlSBox(); });
// event submit
_objs.form.submit(function(){
var self = jQuery(this);
jQuery.ctrlSBox(self.serialize(), function(data){
if(data.auth == true) {
_start = 0; _objs.imsg.val(''); _objs.iaut.val('').focus();
_data = data; jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
} else {
jQuery.jGrowl(data.message);
}
});
return false;
});
});
/*
* show/hide busy image
* @close: if true is hide busy image
*/
jQuery.busySBox = function(close){
if(close == true) {
return jQuery(this).hide();
}
return jQuery(this).show();
}
/*
* load ajax get data response and control heart
* @values: data request
* @fn: function callback
*/
jQuery.ctrlSBox = function(values, fn){
var url = _objs.form.attr('action');
if(typeof values == undefined) {
values = {};
}
jQuery.busySBox.call(_objs.busy);
jQuery.post(url, values, function(data){
if(typeof fn == 'function') {
fn(data);
} else {
_data = data; jQuery.displaySBox.call(_objs.list, jQuery.htmlSBox());
}
jQuery.busySBox.call(_objs.busy, true);
}, 'json');
}
/*
* display HTML data to DOM
* @data: html shoutbox list after processing HTML
*/
jQuery.displaySBox = function(data) {
jQuery(this).html(data).find('li:even').addClass('even');
}
/*
* Data processing returns html
* @data: type JSON
*/
jQuery.htmlSBox = function(){
if(typeof _data == undefined) {
alert("line 97 has bug !"); return false;
}
var html = ['<ul>'];
jQuery.each(_data.items, function(i, item) {
if(i < _start + _rows && i >= _start) {
html.push('<li>');
html.push('<span class="createdDate">' + item.created_date + '</span> ');
html.push('<span class="authorName">' + item.author+ '</span> ');
html.push('<span class="message">' + item.message+ '</span>');
html.push('</li>');
}
}); html.push('</ul>');
return html.join('');
}
Vì demo có Database nên tớ làm biếng tạo DB trên server, các bạn xem demo bằng clip nhé:
Có thể giúp lại được không, mình đang cần nó