Paginador con CodeIgniter
// Diciembre 12th, 2009 // CodeIgniter, PHP
Bueno pues como saben CodeIgniter ya incluye metodos para paginar registros, sin embargo cuando queremos agregar un buscador y que ademas se pueda agregar la url con los resultados a los favoritos o enviar el link a un amigo, es cuando se complica el asunto.
En este post les mostrare como lo resolví, en resumen el formulario de búsqueda envía los parametros por POST a la acción del controlador, el cual se encarga de convertirlos al formato de URI, (ya que CodeIgniter por default no permite el uso del método GET) una vez convertido se aplican los metodos del paginador incluidos en CodeIgniter.
Pueden ver el ejemplo funcionando aquí
Para empezar utilizaremos el ejemplo de un buscador para una libreta de contactos, los códigos se encuentran comentados para una mayor comprensión.
Tabla y algunos registros:
CREATE TABLE IF NOT EXISTS `contactos` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nombre` varchar(200) NOT NULL, `telefono` varchar(200) DEFAULT NULL, `email` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ; INSERT INTO `contactos` (`id`, `nombre`, `telefono`, `email`) VALUES (1, 'Diego Armando Maradona', '5556789865', 'da.maradona@correo.com'), (2, 'Hugo Sanchez Marquez', '5558273910', 'h.sanchez@correo.com'), (3, 'Andrea Pirlo', '5567289392', 'a.pirlo@correo.com'), (4, 'Fernando Torres', '5542637201', 'f.torres@correo.com'), (5, 'Zinedine Zidane', '5521283821', 'zz@correo.com'), (6, 'Patrick Kluivert', '5529832321', 'p.kluivert@correo.com');
Este es el modelo Contacto.php
class Contacto extends Model {
function Contacto()
{
parent::Model();
}
function get_contactos($params, $limit, $offset)
{
$this->db->where($params);
$query = $this->db->get('contactos', intval($limit), intval($offset));
return $query;
}
function get_contactos_count($params = array())
{
$this->db->where($params);
$this->db->from('contactos');
return $this->db->count_all_results();
}
}
Dentro del modelo contamos con los metodos para obtener el total de registros asi como el detalle por página.
En el archivo config.php tengo la configuración para los links del páginador:
$config['paginador_config'] = array(
'full_tag_open' => '<div id="page-nav"><ul>',
'full_tag_close' => '</ul></div>',
'first_link' => '<<',
'first_tag_open' => '<li>',
'first_tag_close'=> '</li>',
'last_link' => '>>',
'last_tag_open' => '<li>',
'last_tag_close' => '</li>',
'next_link' => '>',
'next_tag_open' => '<li>',
'next_tag_close' => '</li>',
'prev_link' => '<',
'prev_tag_open' => '<li>',
'prev_tag_close' => '</li>',
'cur_tag_open' => '<li><span>',
'cur_tag_close' => '</span></li>',
'num_tag_open' => '<li>',
'num_tag_close' => '</li>'
);
Helper personalizado, archivo jacs_helper.php dentro de la carpeta helpers:if ( ! function_exists('search_uri')) { // Esta función recibe la ruta base desde donde corre nuestro script, en este caso "welcome/index" // $data es el arreglo con las condiciones para la consulta function search_uri($basepath, $data) { $CI =& get_instance(); //Obtenemos la instancia de CodeIgniter $uri = array(); foreach($data as $label => $request){ if($request != ''){ // Si el valor viene vacio no se toma en cuenta en las condiciones de la consulta $uri[$label] = $request; } } $url = $CI->uri->assoc_to_uri($uri); // Aqui convertimos nuestro arreglo de condiciones a formato uri. Pueden encontrar mas información de la clase URI en http://codeigniter.com/user_guide/libraries/uri.html redirect($basepath.'/'.$url); // Se realiza un redireccionamiento a nuestra ruta base con las condiciones concatenadas, de esta forma obtenemos una uri similar a: welcome/index/nombre/hugo/email/correo.com } }En es el archivo welcome.php dentro de la carpeta controllers.
class Welcome extends Controller { function Welcome() { parent::Controller(); } function index() { // El helper es cargado de forma automatica en el archivo autoload.php $this->load->model('Contacto'); $this->load->library('pagination'); // Cuando el usuario realiza una consulta, recibimos las condiciones por POST if(!empty($_POST)){ search_uri('/welcome/index',$_POST); // Llamamos al helper que se encargara de hacer un redirect con e formato adecuado } // Para este ejemplo consideramos que el primer segmento del uri es el controlador, // el segundo la acción, por lo tanto las condiciones se encuentran a partir del segmento 3 $condiciones = $this->uri->uri_to_assoc(3); // Las condiciones son representadas en la uri de la forma campo/valor por lo tanto esperamos que el numero de segmentos sea par, // cuando no es par quiere decir que no es la primera pagina y el valor impar representa el offset del paginador if(($this->uri->total_segments()-2)%2!=0){ array_pop($condiciones); //Eliminamos el offset de las condiciones $uri_segment = $this->uri->total_segments(); // La variabel $uri_segment le indica al paginador la posicion del offset }else{ $uri_segment = $this->uri->total_segments()+1; // Si el total de segmentos es par, estamos en la primer pagina } $url = $this->uri->assoc_to_uri($condiciones); // Generamos nuevamente la url para que el paginador la incluya en los links $consulta = $condiciones; // La variable consulta nos servira para recuperar las condiciones en nuestro formulario de busqueda //Las condiciones se recorren y si el valor no es númerico se le agrega LIKE para hacer la consulta foreach($condiciones as $key => $value){ if(!is_numeric($value)) { $condiciones[$key.' LIKE'] = '%'.$value.'%'; unset($condiciones[$key]); } } $per_page = 2; // En esta variable indicamos los registros a mostrar por pagina $total_rows = $this->Contacto->get_contactos_count($condiciones); // Obtenemos el total de registros $offset = $this->uri->segment($uri_segment, 0); // Asignamos el offset $paginador = $this->config->item('paginador_config'); // Obtenemos la configuracion para los links del paginador // Pueden entra a http://codeigniter.com/user_guide/libraries/pagination.html para consutar mas informacion de la configuracion del paginador $paginador['base_url'] = site_url("welcome/index/".$url); $paginador['total_rows'] = $total_rows; $paginador['per_page'] = $per_page; $paginador['uri_segment'] = $uri_segment; $paginador['num_links'] = 4; $this->pagination->initialize($paginador); // Mandamos nuestras variables a la vista $datos = array(); $datos['paginate'] = $this->pagination->create_links(); $datos['contactos'] = $this->Contacto->get_contactos($condiciones,$per_page,$offset); $datos['condiciones'] = $consulta; $datos['titulo']="Contactos"; $this->load->view('welcome_message',$datos); } }Archivo welcome_message.php dentro de la carpeta views:
<?php $this->load->view('layout/header'); ?> <ul id="sort-box"> <li> <div> <div> <h2>Buscar contactos</h2> </div> </div> <div> <form action="" enctype="application/x-www-form-urlencoded" method="post"> <div id="search-bar"> Nombre: <input type="text" name="nombre" value="<?php echo @$condiciones['nombre']; ?>" /> E-mail: <input type="text" name="email" value="<?php echo @$condiciones['email']; ?>" /> <input type="submit" value="Buscar"/> </div> </form> </div> </li> <?php if(isset($contactos)): ?> <li> <div> <div> <h2>Resultados</h2> </div> </div> <div> <?php if($contactos->num_rows() > 0): ?> <table> <thead> <tr> <th> </th> <th>Nombre</th> <th>Teléfono</th> <th>Email</th> </tr> </thead> <tbody> <?php $i = 0; foreach($contactos->result_array() as $contacto): $class = ($i%2!=0)?'':''; ?> <tr<?php echo $class; ?>> <td><?php echo $contacto['id']; ?></td> <td><?php echo $contacto['nombre']; ?></td> <td><?php echo $contacto['telefono']; ?></td> <td><?php echo $contacto['email']; ?></td> </tr> <?php $i++; endforeach; ?> </tbody> </table> <?php echo $paginate; ?> <?php else: ?> <p>No existen resultados.</p> <?php endif; ?> </div> </li> <?php endif; ?> </ul> <?php $this->load->view('layout/footer'); ?>Pueden ver el ejemplo funcionando aquí







