Ken Phan's Blog

Ken Phan Blog
load ...
Anger
Cry
Glad
Happy
Laugh
Quiet
Sad
Silence
Tongue
Undecided
Wink
Trao yêu thương để nhận thương yêu
"To the world you may be one person, but to one person you may be the world ..."

Buôn chuyện

00 / 00
Ken Phan's Blog [kenphan.info] Ken Phan's Blog [kenphan.info] Ken Phan's Blog [kenphan.info] Ken Phan's Blog [kenphan.info] Ken Phan's Blog [kenphan.info] Ken Phan's Blog [kenphan.info]
Bạn đang ở » Trang chủ » Thủ thuật » Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox

Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox

Viết lúc 10:05 ngày 08/04/2010 bởi Administrator .

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.

Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox

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:

1. Hiểu căn bản về jQuery và AJAX
2. Hiểu căn bản về PHP và MySQL
3. Hiểu về JSON data type

Cấu trúc project !?

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

Tạo HTML structure

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>

CSS Style

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;
    cursorefault;
}
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.

Hướng dẫn dùng jQuery (AjAX, JSON), PHP và MySQL tạo shoutbox

Database MySQL

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');

Tạo class database

Ở 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;
    }
}

jQuery Shoutbox

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()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, prevrefresh:

// 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;
});

Tổng kết code js của chúng ta sẽ như sau:

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ảm nhận của mọi người

  • Chuot
    Bản bạn làm xong bị lỗi rồi, bạn xem lại giúp nha.
    2 Replies. Posted at 1 year . Reply
    + 15 points . Good . Bad
    • Nguyen
      bai nay hướng dẩn rất tốt nhưng khi upload lên host thì không chạy, thông tin không hiển thị lên trang index, khi submit thì huyển thẳng đến trang mình tạo action trong index luôn.
      Có thể giúp lại được không, mình đang cần nó
      1 Replies. Posted at 8 months . Reply
      + 15 points . Good . Bad
      • Administrator
        bạn vui lòng chụp lại màn hình, lưu ý là mở firebug rồi hãy chụp nhé. Quăng lên đây mình xem thế nào.
        Posted at 8 months
        + 15 points . Good . Bad
  • hnk8
    Sẽ cố gắng lĩnh hội và chuyển nó qua asp.net
    Posted at 1 year . Reply
    + 15 points . Good . Bad
  • thứ nhất là sau khi cài sql thì phần nội dung chat trong sql không hiển thị ra trên index, thứ 2 sau khi enter thì nó dẫn đến trang php luôn chứ không ở index nữa. Anh xem lại giúp.
    2 Replies. Posted at 1 year . Reply
    + 15 points . Good . Bad
    • Administrator
      vậy là js bị lỗi ùi
      1 Replies. Posted at 1 year . Reply
      + 15 points . Good . Bad
      • Nguyen
        Anh chị giúp em sớm được không? tại em đang cần gấp
        Posted at 8 months
        + 15 points . Good . Bad
  • E co 1 van de ve showbox trong vbb.
    Tinh hinh hien tai e add mod co san cua vbb
    Khi text chat thi cho khugn show text chat se show tu tren xuong duoi.
    E muon cho no show nguoc lai tu duoi len tren thi lam sao a
    Thanks a truoc
    2 Replies. Posted at 1 year . Reply
    + 15 points . Good . Bad
    • Administrator
      mình không sử dụng VBB, bạn thử kiếm đoạn Query thay thể ORDER BY DESC hoặc ASC xem thế nào nhé !!!
      1 Replies. Posted at 1 year . Reply
      + 15 points . Good . Bad
      • aaa
        fasdfasdfsd asd fasd fasd fasdf
        Posted at 9 months
        + 15 points . Good . Bad
  • Băng
    Chào anh! em đọc bài viết của anh rồi. Nhưng em gặp phải vấn đề này rất mong anh giúp em???Em đang sử dụng FW codeigniter mà yêu cầu là tạo menu động và shoutbox lấy từ csdl load lên 1 cách ngẫu nhiên. Anh làm ơ chỉ giùm em với nhen!!!??? càng sớm càng tốt. Cảm ơn anh nhiều!!!^^
    1 Replies. Posted at 1 year . Reply
    + 15 points . Good . Bad
    • Administrator
      bạn có thể dùng hàm random() trong php hoặc Math.random() trong javascript để load ngẫu nhiên nhé. Tìm hiểu thêm trên google 2 hàm đó chúc bạn thành công
      Posted at 1 year . Reply
      + 15 points . Good . Bad
  • bạn ơi gửi cho mình file demo với video hướng dẫn với.
    phần download bị hỏng rồi mình ko down được hixx
    Posted at 4 months . Reply
    + 15 points . Good . Bad