Bài 06: Tải thêm dữ liệu sử dụng jQuery Ajax và PHP từ cơ sở dữ liệu

Ajax 15/03/2017 07:00 2017
Tiếp tục với JQuery ajax, Trong bài viết này mình sẽ hướng dẫn các bạn làm chức năng tải thêm dữ liệu sử dụng JQuery ajax và PHP với MySQL.

Hiện này các trang web như Youtube, Facebook, Twitter đều sử dụng kỹ thuât tải thêm dữ liệu. Thì kỹ thuật này nó có ưu điểm gì? Trước kia chúng ta hay sử dụng phương pháp phân trang, khi người dùng muốn xem các dữ liệu cũ hơn.  Sử dụng kỹ thuật này cho website của bạn sẽ tương tác với người dùng tốt hơn vì website của bạn không phải tải lại trang.

 

Xem demo Download source code

 

Trong bài viết này mình sẽ hướng dẫn các bạn xây dựng một tính năng tương tự như vậy sử dụng JQuery ajax và PHP tải thêm dữ liệu trong CSDL.

Có hai cách giải quyết bài toán này.

  • Người dùng click vào một button như www.chiasephp.net
  • Hệ thống sẽ tự động load khi người dùng kéo thanh scroll bar xuống cuối trang.

Thì hôm nay mình sẽ hướng dẫn các bạn làm tính năng này bằng cách click vào một button trước nhé !

Mình sẽ sử dụng bảng products trong CSDL mẫu.

CREATE TABLE `products` (
  `productCode` varchar(15) NOT NULL,
  `productName` varchar(70) NOT NULL,
  `productLine` varchar(50) NOT NULL,
  `productScale` varchar(10) NOT NULL,
  `productVendor` varchar(50) NOT NULL,
  `productDescription` text NOT NULL,
  `quantityInStock` smallint(6) NOT NULL,
  `buyPrice` decimal(10,2) NOT NULL,
  `MSRP` decimal(10,2) NOT NULL,
  `createDate` int(10) NOT NULL,
  PRIMARY KEY (`productCode`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Mình sẽ hiển thị danh sách sản phầm trong bảng products bằng cách sử dụng câu lệnh SELECT theo cú pháp sau. Lưu ý mình đang sử dụng mệnh đề ORDER BY theo creaDate tăng dần.

SELECT productCode,
        productName,
        quantityInStock,
        buyPrice,
        createDate
FROM products
ORDER BY  createDate ASC

Try In Out

Trong ví dụ này mình sẽ tạo ra ba file.

  • dbconfig.php: File này sẽ định nghĩa các biến và kết nối tới CSDL.
  • index.php : Chứa dữ liệu ban đầu khi người dùng truy cập vào trang và jQuery ajax.
  • ajax_more.php: Load thêm dữ liệu.

Ok ! Chúng ta bắt đầu code nào !

File dbconfig.php

File này sẽ định nghĩa các biến và kết nối tới CSDL.

<?php
	// Các biến chứa thông tin kết nối CSDL
	$db_host = 'localhost';
	$db_user = 'root';
	$db_pass = '';
	$db_name = 'demo';
	// Thiết lập 5 records/trang
	$recordPerPage = 5; 
	
	// Kết nối tới CSDL
	$dbconn = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
	// Kiểm tra kết nối
	if (mysqli_connect_errno($dbconn)) {
		echo "Không thể kết nối tới MySQL: " . mysqli_connect_error();
	}
?>

File index.php

<?php 
// include database configuration file
require_once('dbconfig.php');

// Lấy tổng số records có trong table products
$query = mysqli_query($dbconn,"SELECT COUNT(*) as totalRecords FROM products");
$row = mysqli_fetch_assoc($query);
$totalRecords = $row['totalRecords'];

// Tính tổng số trang và thiết lập $currentPage;
$currentPage = 1;
$totalPage = ceil($totalRecords/$recordPerPage);

// Lấy các dữ liệu ban đầu
$query = mysqli_query($dbconn,"SELECT * FROM products ORDER BY createDate ASC LIMIT 0,$recordPerPage");
?>
<div class="container">
<?php if( mysqli_num_rows($query) > 0){ ?>
	<table border="0" class="tbl-grid" cellpadding="0" cellspacing="0" width="100%">
		<thead>
			<th class="gridheader">Mã sản phầm</th>
			<th class="gridheader">Tên sản phầm</th>
			<th class="gridheader">Số lượng</th>
			<th class="gridheader">Giá bán</th>
			<th class="gridheader">Ngày tạo</th>
		</thead>
	<?php  while($row = mysqli_fetch_array($query)){ ?>
		<tr class="trProducts" createDate="<?php echo $row['createDate']; ?>" >
		        <td><?php echo $row['productCode'] ?></td>
			<td><?php echo $row['productName'] ?></td>
			<td><?php echo $row['quantityInStock'] ?></td>
			<td><?php echo $row['buyPrice'] ?></td>
			<td><?php echo date('d-m-Y',$row['createDate']); ?></td>
		</tr>
	<?php } ?>
	</table>
	<?php if($totalPage > 1){ ?>
		<a href="javacript:void(0)" class="showmorethisresult" total="<?php echo $totalPage; ?>" page="<?php echo ($currentPage+1); ?>">Load more</a>
	<?php } ?>
<?php } ?>
</div>

Mỗi một lần người dùng click vào button Load more thì bạn có thể load thêm một số records nhất định(5 records hoặc 10 records), hoặc bạn sẽ load thêm một trang. Thì trong ví dụ này mình sẽ lựa chọn load thêm một trang, vì đây là cách dễ dàng tính toán nhất dựa trên thuật toán phân trang đơn giản.

Các bạn chú ý dòng code này.

<?php if($totalPage > 1){ ?>
      <a href="javacript:void(0)" class="showmorethisresult" total="<?php echo $totalPage; ?>" page="<?php echo ($currentPage+1); ?>">Load more</a>
<?php } ?>

Thuộc tính total lưu trữ tổng số trang. Thuộc tính page lưu trữ số trang tiếp theo khi người dùng click vào. Thì mỗi lần người dùng click vào button này mình sẽ kiểm tra xem $currentPage + 1 < $totalPage hay không. Nếu nhỏ hơn thì tiếp tục tăng biến $currentPage. Ngược lại thì sẽ ẩn nút Load more.

Javasript Code.

Trước khi bắt đầu code javascipt thì nếu project của bạn chưa include thư viện JQuery thì bạn phải include vào vì trong bài viết này mình sẽ sử dụng JQuery để viêt cho nó nhanh.

<script type="text/javascript">
	$(document).ready(function(){
		$('.showmorethisresult').click(function(){
			var $_this = $(this);
			var $currentPage = parseInt($_this.attr('page'));
			var $totalPage = parseInt($_this.attr('total'));	
			var $createDate = $('.trProducts:last-child').attr('createDate');
				
			$_this.text('Loading...');
			$.post('ajax_more.php',{'createDate':$createDate,'currentPage':$currentPage},function(html){
				$_this.text('Load more');
				$('.tbl-grid .trProducts:last').after(html);
				if(($currentPage+1) < $totalPage){
					$_this.attr('page',($currentPage+1));
				}else{
					$_this.hide();
				}
			});
		});
	});
</script>

Ở đây mình sử dụng phương thức .after() trong JQuery. Mình sẽ chèn vào sau dòng cuỗi cùng của danh sách.

Thực ra có nhiều bạn khi làm tính năng này bạn thường sử dụng cách cộng tăng dần. Nhược điểm của nó là bạn sẽ phải load lại những dữ liệu trước đó bạn đã load.

Trong ví dụ này mình chỉ load những sản phẩm tiếp, mới hơn chứ mình không load lại những sản phầm mình đã load trước đó.

var $createDate = $('.trProducts:last-child').attr('createDate');

Biến này sẽ lấy sản phầm nào mới nhất mà mình đã load trước đó.

File ajax_more.php

<?php 
// include database configuration file
require_once('dbconfig.php');

$createDate = $_POST['createDate'];
$limit = " LIMIT 0,$recordPerPage";
// get rows query
$query = mysqli_query($dbconn,"SELECT * FROM products WHERE createDate>'$createDate' ORDER BY createDate ASC ".$limit);

$html = '';
if(mysqli_num_rows($query) > 0){
	while($row = mysqli_fetch_array($query)){
		$html .= '
		 <tr class="trProducts" createDate="'.$row['createDate'].'">
			<td>'.$row['productCode'].'</td>
			<td>'.$row['productName'].'</td>
			<td>'.$row['quantityInStock'].'</td>
			<td>'.$row['buyPrice'].'</td>
			<td>'.date('d-m-Y',$row['createDate']).'</td>
		</tr>';	
	}
}
#
echo $html; die();
?>

Lưu ý: Trong đoạn code trên mình chỉ lựa chọn những sản phầm nào mới hơn sản phầm cũ trước đó.

Tổng kết.

Trong bài hướng dẫn này mình đã hướng dẫn các bạn hoàn thành kỹ thuật tải thêm dữ liệu. Một kỹ thuật khá hay và có tính ứng dụng rất lớn trong thời gian gần đây. Kỹ thuật này không hề khó khi bạn đã hiểu rõ nguyên lý của nó.

Xem Thêm

Profile photo of adminTheHalfHeart

B.V.T

Sinh ra và lớn nên ở Bắc Giang. Hiện tại thì tôi đang là một lập trình viên tại VietISO. Tôi lập website này với mục đích là bookmark những gì tôi đã đọc qua và mong muốn chia sẻ những gì tôi biết.