|
Server Side \ CakePHP pagination component CakePHP pagination component
Este artículo ha sido consultado en 1,402 ocasiones. Paginación es simplemente presentar una tabla grande en pantallas, es decir poder "hojear" los datos.
Stranger Studios tiene un tutorial sobre como implementar una paginación estilo Digg, aqui siemplemente adapto el código a un componente.
El componente se usa en el controlador agregándolo al array $components:
public $components = array('Portal', 'Mypagination', 'Security');
por ejemplo en el método view() del controlador news_controller.php el paginador se usa asi:
public function view($page=1)
{
$this->pageTitle = 'Hacktivismo::Mononeurona';
//pagination
$total_rows = $this->News->findCount(array("status"=>1));
$lmt = 7; // limit news
$targetpage = "/news/view/"; // URL, this class->method
$pagination = $this->Mypagination->init($total_rows, $page, $lmt, $targetpage);
$this->set('pagination', $pagination);
$conditions = array("News.status"=>1);
$fields = array("News.id", "News.title", "News.body", "News.created", "Theme.img", "Theme.title");
$order = "News.id DESC";
$offset = (($page * $lmt) - $lmt);
$limit = $lmt . " OFFSET " . $offset;
$this->set('data', $this->News->findAll($conditions, $fields, $order, $limit));
}
Necesito OFFSET porque en PostgreSQL se debe declarar de manera explicita, pero si estás en MySQL u Oracle debes quitar el "OFFSET" en $limit.
$this->Mypagination->init regresa el string $pagination, que se incluye en la vista /app/views/news/view.thtml:
< ? php
//pagination
echo $pagination;
?>
El código del componente es este:
< ? php
/**
* Pagination Component, responsible for managing the DATA required for pagination.
* Manuel Montoya GPLv3
* Chipotle Software 2007
* manuel-AT-mononeurona-DOT-org
*/
class MypaginationComponent extends Object
{
//number of rows (items) returned by the query.
private $total_rows;
//limit
private $limit;
// $page is the current page number
public $page;
//URL
public $targetpage;
/**
* Startup - Link the component to the controller.
*
* @param controller
*/
public function startup(&$controller)
{
$this->controller =& $controller;
}
/**
* Initialize the pagination data.
*
* @param unknown
* @param array
* @options array
* @return array
*/
function init($tr, $page, $limit,$targetpage)
{
$this->total_rows = (int) $tr;
$this->page = (int) $page;
$this->limit = (int) $limit;
$this->targetpage = (string) $targetpage;
return $this->getPaginationString();
}
//function to return the pagination string
private function getPaginationString($adjacents = 1)
{
// NEXT CODE BY Stranger Studios http://www.strangerstudios.com/sandbox/pagination/diggstyle.php
//other vars
$prev = $this->page - 1; //previous page is page - 1
$next = $this->page + 1; //next page is page + 1
$lastpage = ceil($this->total_rows / $this->limit); //lastpage is = total items / items per page, rounded up.
//exit($lastpage);
$lpm1 = $lastpage - 1; //last page minus 1
/*
Now we apply our rules and draw the pagination object.
We're actually saving the code to a variable in case we want to draw it more than once.
*/
$pagination = "";
if ($lastpage > 1)
{
$pagination .= '<div class="pagination">'; //just starting
//previous button
if ($this->page > 1)
{
$pagination .= '<a href="'. $this->targetpage. $prev .'"> prev</a>';
}
else
{
$pagination .= '<span class="disabled">prev</span>'; // no such prev page
}
//pages
if ( $lastpage < 7 + ($adjacents * 2)) //not enough pages to bother breaking it up
{
for ($counter = 1; $counter <= $lastpage; $counter++)
{
if ($counter == $this->page)
{
$pagination .= '<span class="current">'.$counter.'</span>'; //current
}
else
{
$pagination .= '<a href="'.$this->targetpage . $counter . '">'.$counter.'</a>';
}
}
}
elseif ($lastpage >= 7 + ($adjacents * 2)) //enough pages to hide some
{
//close to beginning; only hide later pages
if ($this->page < 1 + ($adjacents * 3))
{
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
{
if ($counter == $this->page)
{
$pagination .= '<span class="current">'.$counter.'</span>';
}
else
{
$pagination .= '<a href="'.$this->targetpage . $counter.'">'.$counter.'</a>';
}
}
$pagination .= "...";
$pagination .= '<a href="'.$this->targetpage . $lpm1 .'">'.$lpm1.'</a>';
$pagination .= '<a href="'.$this->targetpage. $lastpage.'">'.$lastpage.'</a>';
}
//in middle; hide some front and some back
elseif ($lastpage - ($adjacents * 2) > $this->page && $this->page > ($adjacents * 2))
{
$pagination .= '<a href="'.$this->targetpage.'">1</a>';
$pagination .= '<a href="'.$this->targetpage.'">2</a>';
$pagination .= '...';
for ($counter = $this->page - $adjacents; $counter <= $this->page + $adjacents; $counter++)
{
if ($counter == $this->page)
{
$pagination .= '<span class="current">'.$counter.'</span>';
}
else
{
$pagination .= '<a href="'.$this->targetpage.$counter.'">'.$counter.'</a>';
}
}
$pagination .= '...';
$pagination .= '<a href="'.$this->targetpage.$lpm1.'">'.$lpm1.'</a>';
$pagination .= '<a href="'.$this->targetpage.$lastpage.'">'.$lastpage.'</a>';
}
else //close to end; only hide early pages
{
$pagination .= '<a href="'.$this->targetpage.'">1</a>';
$pagination .= '<a href="'.$this->targetpage.'">2</a>';
$pagination .= '...';
for ($counter = $lastpage - (1 + ($adjacents * 3)); $counter <= $lastpage; $counter++)
{
if ($counter == $this->page)
{
$pagination .= '<span class="current">'.$counter.'</span>';
}
else
{
$pagination .= '<a href="'.$this->targetpage.$counter.'">'.$counter.'</a>';
}
}
}
}
//next button
if ( $this->page < $counter - 1 )
{
$pagination .= '<a href="'.$this->targetpage . $next.'"> Next </a>';
}
else
{
$pagination .= '<span class="disabled"> Next </span>';
}
$pagination .= '</div>';
}
return $pagination;
}
}
?>
Es necesario agregar unas clases CSS para que se vea estilo Digg:
/* Holly Hack for IE \*/
* html .suckertreemenu ul li { float: left; height: 1%; }
* html .suckertreemenu ul li a { height: 1%; }
/* End */
/** PAGINATION ***/
div.pagination {
padding: 3px;
margin: 3px;
font-size:8pt;
}
div.pagination a {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #fe640d;
text-decoration: none; /* no underline */
font-size:8pt;
color: #fe640d;
}
div.pagination a:hover, div.pagination a:active {
border: 1px solid #000099;
color: #000;
}
div.pagination span.current {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #fe640d;
font-weight: bold;
background-color: #fe640d;
color: #fff;
}
div.pagination span.disabled {
padding: 2px 5px 2px 5px;
margin: 2px;
border: 1px solid #EEE;
color: #c0c0c0;
}
Última actualización: 2007-06-05 03:22:15-05
|