jQuery Ajax scrolling pagination với PHP và MYSQL
Hiện nay có một số website khi các bạn kéo xuống phía dưới cùng thì nó tự động load thêm dữ liệu. Facebook là một ví dụ nhưng nó khác ở chỗ là nó thực hiện hai thao tác, thứ nhất là kéo xuống sẽ load thêm, thứ hai là nó thiết lập sau một thời gian sẽ load thêm. Chức năng này người ta gọi là Ajax Scrolling Pagination.
1. Ajax Scrolling Pagination với PHP và MYSQL
Chúng ta sẽ đi từng phần một để các bạn dễ hiểu bài hơn, quy trình như sau:
- Tạo CSDL và thêm một số record để test
- Tạo file hiển thị danh sách
- Dùng jQuery xử lý sự kiện Scrolling và gọi ajax
Mỗi bước chúng ta sẽ có những đoạn code liên kết với nhau nên các bạn đọc kỹ bài viết nhé.
Tạo database để phân trang khi scrolling
Tạo database:
Bài viết này được đăng tại [free tuts .net]
CREATE TABLE IF NOT EXISTS `tb_customer` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL, `website` VARCHAR(255) COLLATE utf8_unicode_ci DEFAULT NULL, UNIQUE KEY `id` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=11 ;
Thêm một vài record:
INSERT INTO `tb_customer` (`id`, `name`, `website`) VALUES (1, 'Nguyễn Văn Cường', 'freetuts.net'), (2, 'Trương Phúc Hoài Minh', 'freetuts.net'), (3, 'Đặng Văn Chương', 'freetuts.net'), (4, 'Trương Tấn Thành', 'freetuts.net'), (5, 'Lâm văn Lang', 'demo.com'), (6, 'Nguyễn Văn Kiệt', 'ajax.com'), (7, 'Nguyễn Thị Nở', 'thimau.com'), (8, 'Đặng Thị Thoa', 'scrolling.com'), (9, 'Trương Văn Kiệt', 'ajaxscrolling.com'), (10, 'Đặng Thị Tâm', 'nono.com');
Tạo file hiển thị kết quả phân trang khi scrolling
Bạn tạo file list.php
với nội dung như sau:
<!DOCTYPE html> <html> <head> <title></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script> <script language="javascript" src="ajax.js" ></script> <style type="text/css"> #loadding {color:red; font-size: 20px; font-weight: bold; text-align: center} .item {height: 500px; border: solid 2px blue; background: #CCCCCC; line-height: 500px; color: blue; text-align: center; font-weight: bold; margin: 20px 0px;} .hidden {display: none} </style> </head> <body> <div id="content"> <?php require('data.php'); ?> </div> <div id="loadding" class="hidden"> LOADDING ... </div> </body> </html>
Trong file này tôi có thêm thư viện jQuery
, file ajax.js
và tạo hai thẻ div như sau:
<div id="content">
dùng để hiển thị danh sách, trong này tôi có require filedata.php
mà chúng ta sẽ tạo ở bước tiếp theo<div id="loadding" class="hidden">
dùng để hiển thị chữ loadding khi gửi ajax
Viết jQuery Ajax Scrolling Pagination
Bạn tạo file ajax.js
với nội dung như sau, lưu ý là file này mình đã import vào file list.php
ở bước trên.
// Biến dùng kiểm tra nếu đang gửi ajax thì ko thực hiện gửi thêm var is_busy = false; // Biến lưu trữ trang hiện tại var page = 1; // Biến lưu trữ rạng thái phân trang var stopped = false; $(document).ready(function() { // Khi kéo scroll thì xử lý $(window).scroll(function() { // Element append nội dung $element = $('#content'); // ELement hiển thị chữ loadding $loadding = $('#loadding'); // Nếu màn hình đang ở dưới cuối thẻ thì thực hiện ajax if($(window).scrollTop() + $(window).height() >= $element.height()) { // Nếu đang gửi ajax thì ngưng if (is_busy == true){ return false; } // Nếu hết dữ liệu thì ngưng if (stopped == true){ return false; } // Thiết lập đang gửi ajax is_busy = true; // Tăng số trang lên 1 page++; // Hiển thị loadding $loadding.removeClass('hidden'); // Gửi Ajax $.ajax( { type : 'get', dataType : 'text', url : 'data.php', data : {page : page}, success : function (result) { $element.append(result); } }) .always(function() { // Sau khi thực hiện xong ajax thì ẩn hidden và cho trạng thái gửi ajax = false $loadding.addClass('hidden'); is_busy = false; }); return false; } }); });
File này tôi đã comment rất kỹ rồi, chung quy lại ý tưởng như sau:
- Tạo các biến
is_busy
,page
,stopped
để lưu các thông số kiểm tra khi phân trang - Thực hiện phân trang khi màn hình kéo xuống dưới cùng
- Trước khi gửi phải kiểm tra các giá trị các biến toàn cục để quyết định gửi ajax hay không, đồng thời hiển thị chữ loadding nếu cho phép gửi ajax
- Sau khi gửi ajax thì ẩn nút loadding
- Sử dụng sử dụng phương thức GET trong jquery ajax để gửi.
Tạo file data.php để thực hiện truy vấn dữ liệu
File này khá là quan trọng đấy, nó có hai nhiệm vụ là :
- Import vào file list.php trong div có
id = content
. - Ajax sẽ gọi đến file này
Nội dung như sau:
<?php // Bước này dùng để kiểm tra thôi chứ ko có tác dụng gì // Mục đích là ngưng xử lý 3 giây để mình xem dòng chữ loadding // Sau khi test xong bạn xóa đi nhé if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){ sleep(1); } // Thiết lập kết quả trả về là html và charset là utf8 để khỏi lỗi font header('Content-Type: text/html; charset=utf-8'); // Kết nối database $conn = mysqli_connect('localhost', 'root', 'vertrigo', 'demo') or die ('Không thể kết nối đến CSDL'); mysqli_set_charset($conn, 'utf8'); // Lấy trang hiện tại $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; // Kiểm tra trang hiện tại có bé hơn 1 hay không if ($page < 1) { $page = 1; } // Số record trên một trang $limit = 3; // Tìm start $start = ($limit * $page) - $limit; // Câu truy vấn // Trong câu truy vấn này chúng ta sẽ lấy limit tăng lên 1 // Lý do là vì ta không có viết code đếm record nên dựa vào tổng số kết quả trả về để: // - Nếu kết quả trả về bằng $limit + 1 thì còn phân trang // - Nếu kết quả trả về bé hơn $limit + 1 thì nghĩa là hết dữ liệu nên ngưng phân trang $sql = "select * from tb_customer limit $start,".($limit + 1); // Thực hiện câu truy vấn $query = mysqli_query($conn, $sql) or die ('Lỗi câu truy vấn'); // Duyệt kết quả rồi đưa vào mảng result $result = array(); while ($row = mysqli_fetch_array($query)) { // Thêm vào result array_push($result, $row); } // Hiển thị dữ liệu $total = count($result); // Bỏ đi kết quả cuối cùng vì kết quả này dùng để check phân trang thôi // Tuy nhiên chỉ bỏ ở trường hợp ($total > $limit) nếu không ở trang cuối cùng sẽ mất một row if ($total > $limit){ for ($i = 0; $i < $total - 1; $i++) { echo '<div class="item">'; echo $result[$i]['id'].' - '.$result[$i]['name'].' - '.$result[$i]['website']; echo '</div>'; } } else{ for ($i = 0; $i < $total; $i++) { echo '<div class="item">'; echo $result[$i]['id'].' - '.$result[$i]['name'].' - '.$result[$i]['website']; echo '</div>'; } } // Nếu hết dữ liệu thì stop không phan trang nữa // Ta chỉ cần kiểm tra xem tổng số record có nhiều hơn limit hay không // vì trong câu truy vấn mình select với limit = limit + 1 if ($total <= $limit){ echo '<script language="javascript">stopped = true; </script>'; } ?>
Trong file này các bạn cần lưu ý các vấn đề như sau:
- Ở trên cùng mình có sử dụng hàm sleep để ngưng xủ lý 1 giây mục đích là cho dòng chữ loadding được hiển thị ra để test, nếu không nó xử lý nhanh quá chúng ta không thấy.
- Ở đây ta không cần đếm tổng số record mà sử dụng một mẹo đơn giản đó là lấy dư thêm 1 record, nếu kết quả trả về có số record dư 1 thì nghĩa là còn data, ngược lại hết data.
- Ở đoạn code dưới cùng mình có check nếu hết data thì xuất một đoạn mã javascript gán biến
stopped = true
, biến này chính là biên mà ta khai báo toàn cục ở fileajax.js
Như vậy là hết rồi, bạn chạy lên và xem thành quả của mình nhé.
2. Lời kết
Bài này cũng hơi ngắn và mình viết ở dạng jquery thuần chứ không đưa nó vào jquery plugin, nếu bạn rành jquery thì có thể đưa nó vào mọt plugin để sử dụng cho tiện. Hy vọng qua bài jQuery Ajax Scrolliing Pagination sẽ giúp các bạn thực hiện được thao tác phân trang ajax scrolling rất hay này.
Danh sách file tải về
Tên file tải về | Pass giải nén |
---|---|
Tải bài học định dạng PDF | freetuts.net hoặc gameportable.net |