Diferencia entre revisiones de «Paginadores»

De KumbiaPHP Framework Wiki
Línea 161: Línea 161:
 
<p>En este caso lo muestro en el IndexController que es el controllador por defecto de KumbiaPhp</p>
 
<p>En este caso lo muestro en el IndexController que es el controllador por defecto de KumbiaPhp</p>
 
<code>
 
<code>
<?php  
+
<pre>
 +
<?php  
 
class IndexController extends AppController
 
class IndexController extends AppController
 
{
 
{
Línea 173: Línea 174:
 
}
 
}
 
?>
 
?>
 +
</pre>
 
</code>
 
</code>
 
<p>Si se dan cuenta el Controller, recibe dos parámetros, que son las páginas que mostrará cada lista...
 
<p>Si se dan cuenta el Controller, recibe dos parámetros, que son las páginas que mostrará cada lista...
 
El primer parámetro para Lista de Articulos y el Segundo para Lista de Votados, esto hará que los paginadores sean independientes uno del otro. Con esto Evitaremos que al darle click a "next" de un paginador, el otro paginador tambien cambie de página.</p>
 
El primer parámetro para Lista de Articulos y el Segundo para Lista de Votados, esto hará que los paginadores sean independientes uno del otro. Con esto Evitaremos que al darle click a "next" de un paginador, el otro paginador tambien cambie de página.</p>
  
<p>Ahora verémos la vista</p>
+
<h2>Ahora verémos la vista</h2>
  
 
<code>
 
<code>
  
        <b>Lista de Articulos</b>  
+
    <pre> <b>Lista de Articulos</b>
  
           <center> <?php if($listaArticulos->prev) echo Html::linkAction("index/$listaArticulos->prev/$listaVotados->current", '<< Anterior |'); ?>
+
           <?php if($listaArticulos->prev) echo Html::linkAction("index/$listaArticulos->prev/$listaVotados->current", '<< Anterior |'); ?>
             <?php if($listaArticulos->next) echo Html::linkAction("index/$listaArticulos->next/$listaVotados->current", '| Proximo >>'); ?><br></center>
+
             <?php if($listaArticulos->next) echo Html::linkAction("index/$listaArticulos->next/$listaVotados->current", '| Proximo >>'); ?><br>
 
      
 
      
             <center><b>Articulos Mas Votados</b> </center>
+
             <b>Articulos Mas Votados</b>
          <center> <?php if($listaVotados->prev) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->prev", '<< Anterior |'); ?>
+
            <?php if($listaVotados->prev) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->prev", '<< Anterior |'); ?>
             <?php if($listaVotados->next) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->next", '| Proximo >>'); ?><br></center>
+
             <?php if($listaVotados->next) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->next", '| Proximo >>'); ?><br>
 +
    </pre>
 
</code>
 
</code>
 
<p>Si nos damos cuenta la clase paginate del core/libs/kumbia_active_record/behaviors/paginate.php</p>
 
<p>Si nos damos cuenta la clase paginate del core/libs/kumbia_active_record/behaviors/paginate.php</p>
Línea 194: Línea 197:
 
<br>
 
<br>
 
//Atributo->next : página siguiente
 
//Atributo->next : página siguiente
$page->next = ($start + $per_page) < $n ? ($page_number + 1) : false;<br>
+
$page->next = ($start + $per_page) < $n ? ($page_number + 1) : false;</br>
 
//Atributo->prev :página Anterior
 
//Atributo->prev :página Anterior
         $page->prev = ($page_number > 1) ? ($page_number - 1) : false;<br>
+
         $page->prev = ($page_number > 1) ? ($page_number - 1) : false;</br>
 
     //Atributo->current :página Actual
 
     //Atributo->current :página Actual
         $page->current = $page_number;<br>
+
         $page->current = $page_number;</br>
 
     //Atributo->total : Es el total de páginas que tendrá nuestro paginador a recorrer
 
     //Atributo->total : Es el total de páginas que tendrá nuestro paginador a recorrer
         $page->total = ceil($n / $per_page);<br>
+
         $page->total = ceil($n / $per_page);</br>
 
     //Atributo->Count: total de registros a paginar
 
     //Atributo->Count: total de registros a paginar
         $page->count = $n;<br>
+
         $page->count = $n;</br>
 
     //Atributo->per_page :Límite de páginas a mostrar, normalmente se usa en el modelo
 
     //Atributo->per_page :Límite de páginas a mostrar, normalmente se usa en el modelo
         $page->per_page = $per_page;<br>
+
         $page->per_page = $per_page;</br>
 
</p>
 
</p>
  
<p>Para terminar, mostraré el modelo a realizar</p>
+
<h2>Para terminar, mostraré el modelo a realizar</h2>
 
<code>
 
<code>
  
<?php  
+
<pre>
 +
<?php  
 
class Articulos extends ActiveRecord {
 
class Articulos extends ActiveRecord {
 
     // $ppage define el numero de registros que se veran antes que aparezca los link de paginacion
 
     // $ppage define el numero de registros que se veran antes que aparezca los link de paginacion
Línea 222: Línea 226:
 
     }
 
     }
 
?>
 
?>
 +
</pre>
 
</code>
 
</code>

Revisión del 15:44 17 mar 2013

Para la paginación existen dos funciones encargadas de esto:

Paginate

Este es capaz de paginar arrays o modelos, recibe los siguientes parámetros:

Para array:

$s : array a paginar.

page: numero de página.

per_page: cantidad de elementos por página.

Ejemplo:

$page = paginate($s, 'per_page: 5', 'page: 1');

Para modelo:

$s: string con nombre de modelo u objeto ActiveRecord.

page: número de página.

per_page: cantidad de elementos por página.

Asimismo recibe todos los parámetros que pueden utilizarse en el método “find” de ActiveRecord.

Ejemplos:

$page = paginate('usuario', 'NOT login=”admin”', 'order: login ASC', 'per_page: 5', 'page: 1');
$page = paginate($this->Usuario, 'NOT login=”admin”', 'order: login ASC', 'per_page: 5', 'page: 1');

Paginate_by_sql

Efectúa paginación a través de una consulta sql. Recibe los siguientes parámetros:

$model: string nombre de modelo o objeto ActiveRecord.

$sql: string consulta sql.

Ejemplo:

$page = paginate_by_sql('usuario', 'SELECT * FROM usuario WHERE nombre LIKE “%emilio%” ', 'per_page: 5', 'page: 1');

Ambos tipos de paginadores retornan un objeto “page”, este objeto “page” es creado a partir de stdClass, contiene los siguientes atributos:

next: número de página siguiente, si no hay pagina siguiente vale “false”.

prev: número de página anterior, si no hay pagina anterior vale “false”.

current: número de página actual.

total: número de paginas totales.

items: array de elementos paginados.

Paginando en ActiveRecord

ActiveRecord ya trae integrado los métodos paginate y paginate_by_sql, se comportan igual que paginate y paginate_by_sql, sin embargo no es necesario pasar el modelo a paginar ya que por defecto toman el modelo que invoca.

Ejemplo:

$page = $this->Usuario->paginate('per_page: 5', 'page: 1');

Ejemplo completo de uso del paginador:

Tenemos una tabla usuario con su correspondiente modelo Usuario, entonces creemos un controlador el cual pagine una lista de usuarios y asimismo permita buscar por nombre, aprovecharemos la persistencia de datos del controlador para hacer una paginación inmune a inyección sql.

En el controlador:

class UsuarioController extends ApplicationController {
  private $_per_page = 7;
  /**
  * Formulario de busqueda
  **/
  public function buscar() {
    $this->nullify('page', 'conditions');
  }
  /**
  * Paginador
  **/
  public function lista($page='') {
    /**
    * Cuando se efectua la busqueda por primera vez
    **/
    if($this->has_post('usuario')) {
      $usuario = $this->post('usuario', 'trim', 'addslashes');
      if($usuario['nombre']) {
        $this->conditions = “ nombre LIKE '%{$usuario['nombre']}%' ”;
      }
      /**
      * Paginador con condiciones o sin condiciones
      **/
      if(isset($this->conditions) && $this->conditions) {
        $this->page = $this->Usuario->paginate($this->conditions, “per_page: $this>_per_page”, 'page: 1');
      } else {
        $this->page = $this->Usuario->paginate(“per_page: $this>_per_page”, 'page: 1');
      }
    } elseif($page='next' && isset($this->page) && $this->page->next) {
       /**
       * Paginador de pagina siguiente
       **/
      if(isset($this->conditions) && $this->conditions) {
        $this->page = $this->Usuario->paginate($this->conditions, “per_page: $this>_per_page”, “page: {$this->page->next}”);
      } else {
         $this->page = $this->Usuario->paginate(“per_page: $this->_per_page”, “page: {$this->page->next}”);
      }
    } elseif($page='prev' && isset($this->page) && $this->page->prev) {
      /**
      * Paginador de pagina anterior
      **/
      if(isset($this->conditions) && $this->conditions) {
        $this->page = $this->Usuario->paginate($this->conditions, “per_page: $this->_per_page”, “page: {$this->page->prev}”);
    } else {
       $this->page = $this->Usuario->paginate(“per_page: $this->_per_page”, “page: {$this->page->prev}”);
    }
  }
 }
}


En la vista buscar.pthml

<?php echo form_tag('usuario/lista') ?>
<?php echo text_field_tag('usuario.nombre') ?>
<?php echo submit_tag('Consultar') ?>
<?php echo end_form_tag() ?>


En la vista lista.phtml

<table>
<tr>
<th>id</th>
<th>nombre</th>
</tr>
<?php foreach($page->items as $p): ?>
<tr>
<td><?php echo $p->id ?></td>
<td><?php echo h($p->nombre) ?></td>
</tr>
<?php endforeach; ?>
</table>
<br>
<?php if($page->prev) echo link_to('usuario/lista/prev', 'Anterior') ?>
<?php if($page->next) echo ' | ' . link_to('usuario/lista/next', 'Siguiente') ?>

Paginadores Múltiples en una acción

Si queremos tener dos o más paginares en una sola acción:

Ejemplo:

Querémos mostrar en este caso dos lista paginadas, una de artículos y otra de artículos votados - estos votos fueron hechos con anterioridad, con el fin de saber los artículos que a las personas les gusten mas -

En este caso lo muestro en el IndexController que es el controllador por defecto de KumbiaPhp

	<?php 
class IndexController extends AppController
{

    public function index($page=1,$pag=1){
        $articulos = new Articulos();
        	$this->listaArticulos = $articulos->getMenus($page);
        	$this->listaVotados = $articulos->numeroVotos($pag);  
	}

}
?>

Si se dan cuenta el Controller, recibe dos parámetros, que son las páginas que mostrará cada lista... El primer parámetro para Lista de Articulos y el Segundo para Lista de Votados, esto hará que los paginadores sean independientes uno del otro. Con esto Evitaremos que al darle click a "next" de un paginador, el otro paginador tambien cambie de página.

Ahora verémos la vista

 <b>Lista de Articulos</b>

           <?php if($listaArticulos->prev) echo Html::linkAction("index/$listaArticulos->prev/$listaVotados->current", '<< Anterior |'); ?>
            <?php if($listaArticulos->next) echo Html::linkAction("index/$listaArticulos->next/$listaVotados->current", '| Proximo >>'); ?><br>
     
            <b>Articulos Mas Votados</b>
            <?php if($listaVotados->prev) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->prev", '<< Anterior |'); ?>
            <?php if($listaVotados->next) echo Html::linkAction("index/$listaArticulos->current/$listaVotados->next", '| Proximo >>'); ?><br>
     

Si nos damos cuenta la clase paginate del core/libs/kumbia_active_record/behaviors/paginate.php

Aquí tenemos estos Atributos de la clase que nos permitirán saber las páginas de nuestro paginador
//Atributo->next : página siguiente $page->next = ($start + $per_page) < $n ? ($page_number + 1) : false;
//Atributo->prev :página Anterior $page->prev = ($page_number > 1) ? ($page_number - 1) : false;
//Atributo->current :página Actual $page->current = $page_number;
//Atributo->total : Es el total de páginas que tendrá nuestro paginador a recorrer $page->total = ceil($n / $per_page);
//Atributo->Count: total de registros a paginar $page->count = $n;
//Atributo->per_page :Límite de páginas a mostrar, normalmente se usa en el modelo $page->per_page = $per_page;

Para terminar, mostraré el modelo a realizar

		<?php 
	class Articulos extends ActiveRecord {
    // $ppage define el numero de registros que se veran antes que aparezca los link de paginacion
	//en este caso, quiero que se muestren 13 filas de mi base de datos.. Esto es depende del
    public function getMenus($page, $ppage=13)
    {
        return $this->paginate("page: $page", "per_page: $ppage", 'order: id desc');
    }
    public function numeroVotos($page, $ppage=13){
        return $this->paginate("page: $page", "per_page: $ppage", 'order: votos desc');
    }
	 ?>