Chào cả nhà!
Thật không nhớ nổi đây là lần thứ mấy tôi viết bài với tiêu đề phân trang tìm kiếm cho cakephp nữa. Vậy tại sao lại còn có bài viết này nữa. Việc phân trang tìm kiếm với cakephp đã không biết bao nhiêu lần làm tôi đâu đầu rồi. Sau nhiều lần tìm kiếm các giải pháp, nay tôi cũng đa tìm ra một giải pháp ứng ý trong việc tìm kiếm phân trang với cakephp. Sau đây tôi sẽ chia sẽ với mọi người giải pháp ấy, được minh họa thông qua ví dụ tìm kiếm sản phẩm dưới đây.
Việc đâu tiên là tôi phải tạo csdl. Trong ví dụ này tôi tạo csdl có tên là phantrang:
CREATE DATABASE phantrang;
CREATE TABLE IF NOT EXISTS `products` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`model` varchar(255) NOT NULL,
`price` int(16) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`type` enum(‘Loai 1′,’Loai 2′,’Loai 3′) DEFAULT NULL,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
Vậy là tôi đã tạo xong CSDL, còn việc config để kết nối vào CSDL vừa tạo thì mọi người tự làm nhé. Dữ liệu trong đây thì mọi người tự thêm vào nhé.(^_^).
Công việc tiếp theo là tôi sẽ tạo ra một /app/controllers/products_controllers.php như sau:
/* app/controllers/products_controller.php */
class ProductsController extends AppController {
var $name = ‘Products’;
var $scaffold;}
?>
Với các chức năng như add, edit, delete trong ví dụ này tôi sẽ dùng chức năng scaffold của cakephp, và quả thật những trường hợp như thế này thì scaffold quá tuyệt vời. Trong bài viết này tôi sẽ chỉ chú trọng vào chức năng tìm kiếm mà thôi. Tiếp đến tôi sẽ tạo một function search trong products_controller như sau:
/* app/controllers/products_controller.php */
class ProductsController extends AppController {
var $name = ‘Products’;
var $scaffold;function search() {
}
}
?>
Cả nhà chú ý nhé, khi tôi thêm dữ liệu vào thì tôi sẽ copy lại nguyên nội dung của cả trang để mọi người dễ hiểu hơn, chỉ phần nào thêm mới tôi sẽ in đậm lên thôi. Bây giờ tôi sẽ tạo một trang view search như sau app/views/products/search.ctp
// app/view/products/search.ctp
echo $form->create(‘Search’, array(‘url’ => ‘/products/dataSearch’));
echo $form->input(‘name’);
echo $form->input(‘price’);
echo $form->input(‘model’);
echo $form->input(‘type’, array(‘options’ => array(” => ”,’Loai 1′ => ‘Loại 1′, ‘Loai 2′ => ‘Loại 2′, ‘Loai 3′ => ‘Loai 3′)));
echo $form->input(‘description’);
echo $form->end(‘Search’);?>
Phần form search vừa rồi tôi đã đề ‘url’ trỏ đến action ‘dataSearch’. Action ‘dataSearch’ này trong đây sẽ thực hiện công việc xử lý dữ liệu trong form tìm kiếm và chuyển lên url. Tôi thêm function dataSearch trong products_controller như sau:
/* app/controllers/products_controller.php */
class ProductsController extends AppController {
var $name = ‘Products’;
var $scaffold;function search()
{
}function dataSearch()
{
// the page we will redirect to
$url['controller'] = ‘products’;
$url['action'] = ’search’;// build a URL will all the search elements in it
// the resulting URL will be
// example.com/cake/posts/index/Search.keywords:mykeyword/Search.tag_id:3
foreach ($this->data as $k=>$v){
foreach ($v as $kk=>$vv){
$url[$k.'.'.$kk]=$vv;
}
}// redirect the user to the url
$this->redirect($url, null, true);
}
}
?>
Hàm dataSearch sẽ thực hiện chức năng chuyển tòan bộ dữ liệu vừa được gửi (submit) vào trong một mảng và sau đó thông qua hàm ‘redirect’ chuyến sang một trang mới. Việc chuyển đến trang nào sẽ được quyết định thông qua 2 biến “$url['controller']” và “$url['action']” . Nếu bạn nào chưa hiểu hàm này thực hiện những công việc gì thì các bạn cũng không cần tìm hiểu đâu, vì hàm này sẽ không bào giờ thay đổi cả, chỉ cần thay đổi giá trị 2 biến đó thôi. Cả nhà có thể tạm hiểu là hàm này thực hiện việc chuyển tất cả dữ liệu được submit lên trên url.
Vậy là sau khi hàm dataSearch xử lý xong, sẽ chuyển dữ liệu về action “search” trong products_controller. Lúc này sẽ tồn tại một biến mảng “$this->passedArgs” chứa dữ liệu của trang search khi submit. Hay nói đúng hơn biến “$this->passedArgs” chứa các dữ liệu được truyền ở phía trên url và đưa vào thành các mảng tương ứng. Ta sẽ xử lý dữ liệu truyền vào để tạo điều kiện lọc như sau:
/* app/controllers/products_controller.php */
class ProductsController extends AppController {
var $name = ‘Products’;
var $scaffold;function search()
{
$conditions = array();
if (!empty($this->passedArgs))
{
if (isset($this->passedArgs['Search.name']))
{
$conditions[]["Product.name LIKE"] = “%{$this->passedArgs['Search.name']}%”;
$this->data['Search']['name'] = $this->passedArgs['Search.name'];
}if (isset($this->passedArgs['Search.price']))
{
$conditions[]["Product.price "] = $this->passedArgs['Search.price'];
$this->data['Search']['price'] = $this->passedArgs['Search.price'];
}if (isset($this->passedArgs['Search.model']))
{
$conditions[]["Product.model"] = $this->passedArgs['Search.model'];
$this->data['Search']['model'] = $this->passedArgs['Search.model'];
}if (isset($this->passedArgs['Search.type']))
{
$conditions[]["Product.type"] = $this->passedArgs['Search.type'];
$this->data['Search']['type'] = $this->passedArgs['Search.type'];
}
}$this->paginate = array(‘limit’ => ‘1′, ‘order’ => ‘Product.created DESC’);
$this->set(‘products’, $this->paginate(‘Product’, $conditions));
}function dataSearch()
{
// the page we will redirect to
$url['controller'] = ‘products’;
$url['action'] = ’search’;// build a URL will all the search elements in it
// the resulting URL will be
// example.com/cake/posts/index/Search.keywords:mykeyword/Search.tag_id:3
foreach ($this->data as $k=>$v){
foreach ($v as $kk=>$vv){
$url[$k.'.'.$kk]=$vv;
}
}// redirect the user to the url
$this->redirect($url, null, true);
}
}
?>
Trong phần controller này ta sẽ thưc hiện phân trang như bình thường trong cakephp, chỉ khác là sẽ có thêm điều kiện tìm kiếm như ở phía trên thôi.
Việc tiếp theo sẽ là hiển thị kết quả tìm kiếm ra trang search. Ta sẽ thêm vào view search như sau:
/* app/views/products/search.ctp */
echo $form->create(‘Search’, array(‘url’ => ‘/products/dataSearch’));
echo $form->input(‘name’);
echo $form->input(‘price’);
echo $form->input(‘model’);
echo $form->input(‘type’, array(‘options’ => array(” => ”,’Loai 1′ => ‘Loại 1′, ‘Loai 2′ => ‘Loại 2′, ‘Loai 3′ => ‘Loai 3′)));
echo $form->input(‘description’);
echo $form->end(‘Search’);?>
echo $paginator->counter(array(
‘format’ => ‘Page %page% of %pages%, showing %current% records out of
%count% total, starting on record %start%, ending on %end%’
));
?>
ID
Name
Model
Price
Created
Type
Description
foreach ($products as $product)
{
?>
=$product['Product']['id']?>
=$product['Product']['name']?>
=$product['Product']['model']?>
=$product['Product']['price']?>
=$product['Product']['created']?>
=$product['Product']['type']?>
=$product['Product']['description']?>
}
?>
$paginator->options(array(‘url’ => $this->passedArgs));
echo $paginator->prev(‘« Previous ‘);
echo $paginator->numbers();
echo $paginator->next(‘ Next »’);
?>
Trong phần view trên thì dòng quan trọng nhất chính là “$paginator->options(array(‘url’ => $this->passedArgs));”. Dòng này có tác dụng là sẽ truyền toàn bộ các tham số trong mảng “$this->passedArgs” lên trên url của các link phân trang trong cake. Như vậy có nghĩa là các điều kiện tìm kiếm sẽ vẫn còn khi mọi người chuyển trang. Vậy là tôi đã thực hiện xong việc phân trang tìm kiếm trong cakephp1.2 rồi. Mọi người vào đọc thấy có gì thấy khó hiểu thì comment vào nhé. Tôi sẽ sửa lại cho dễ hiểu hơn.
Chúc cả nhà vui vẻ với cakephp nhé.
(i-php.net)