Paginado remoto en un Grid
Jul 08, 2009 | Español | By Crysfel | 27 CommentsEl día de hoy voy a mostrar como podemos paginar los registros de una tabla, esta funcionalidad es muy utilizada cuando tenemos una gran cantidad de información para mostrar al usuario.
El ejercicio de hoy lo puedes ver en acción, a continuación te muestro una imagen de lo que tendremos al final del tutorial.
Ejercicio final
Material de apoyo
Antes de continuar es necesario descargar el material de apoyo y copiar los archivos dentro de la carpeta “grids” que se encuentra en el servidor Web que instalamos en el primer capitulo y en el cual hemos estado trabajando.
Definir el “namespace”
Antes que cualquier otra cosa necesitamos definir el “namespace” donde estaremos trabajando.
Ext.ns('com.quizzpot.tutorial');
com.quizzpot.tutorial.PagingTutorial = {
init: function(){
//code goes here
}
}
Ext.onReady(com.quizzpot.tutorial.PagingTutorial.init,com.quizzpot.tutorial.PagingTutorial);
El paginado
Vamos a paginar la información en el servidor, éste recibirá dos parámetros, “start” y “limit”, estos parámetros son enviados automáticamente por la barra paginadora.
<?php
header("Content-Type: text/plain");
$start = isset($_POST['start'])?$_POST['start']:0; //posición a iniciar
$limit = isset($_POST['limit'])?$_POST['limit']:5; //número de registros a mostrar
$data = array(
array('city'=>'Mexico city','visits'=>684,'pageVisits'=>4.11,'averageTime'=>'00:06:53'),
array('city'=>'La Victoria','visits'=>443,'pageVisits'=>4.39,'averageTime'=>'00:07:28'),
array('city'=>'Madrid','visits'=>380,'pageVisits'=>3.11,'averageTime'=>'00:05:22'),
array('city'=>'Providencia','visits'=>204,'pageVisits'=>3.83,'averageTime'=>'00:08:20'),
array('city'=>'Bogota','visits'=>204,'pageVisits'=>3.26,'averageTime'=>'00:04:57'),
array('city'=>'Puerto Madero','visits'=>192,'pageVisits'=>3.56,'averageTime'=>'00:05:07'),
array('city'=>'Monterrey','visits'=>174,'pageVisits'=>3.90,'averageTime'=>'00:06:06'),
array('city'=>'Barcelona','visits'=>145,'pageVisits'=>3.28,'averageTime'=>'00:05:39'),
array('city'=>'Caracas','visits'=>132,'pageVisits'=>4.55,'averageTime'=>'00:06:27'),
array('city'=>'Rosario','visits'=>116,'pageVisits'=>2.44,'averageTime'=>'00:04:30'),
array('city'=>'Oaxaca','visits'=>108,'pageVisits'=>1.73,'averageTime'=>'00:02:37'),
array('city'=>'Buenos Aires','visits'=>100,'pageVisits'=>5.43,'averageTime'=>'00:07:37'),
array('city'=>'Galicia','visits'=>96,'pageVisits'=>1.92,'averageTime'=>'00:04:37'),
array('city'=>'Guadalajara','visits'=>90,'pageVisits'=>5.92,'averageTime'=>'00:03:37')
);
$paging = array(
'success'=>true,
'total'=>count($data), //<--- total de registros a paginar
'data'=> array_splice($data,$start,$limit)
);
echo json_encode($paging);
?>
El código anterior viene con el material de apoyo, realmente no tiene nada especial únicamente recibe los parámetros y mediante la función “array_splice” regresa los registros solicitados, es importante mencionar que esta información puede provenir de una base de datos o de cualquier otro lugar, pero lo que si debes tener en cuenta es que la paginación depende totalmente del servidor y éste es el responsable de regresar la información correcta.
Crear el Store
El siguiente paso es crear un JsonStore para solicitar los registros por medio de Ajax de la siguiente manera:
var store = new Ext.data.JsonStore({
url: 'paging.php',
root: 'data',
totalProperty: 'total', // <--- total de registros a paginar
fields: ['city','visits','pageVisits','averageTime']
});
store.load();
Si has venido siguiendo el curso desde el principio el código anterior debe ser familiar, la única propiedad que quiero resaltar es “totalProperty” ya que esta propiedad define donde se encuentra (en la información que nos regresa el servidor) el total de los elementos a paginar; si no configuramos la propiedad antes mencionada, el componente no podrá calcular el número de páginas porque supone que el total es solamente los registros que se están mostrando actualmente, por lo tanto no permitirá seguir paginando la información.
Crear el Grid
Vamos a crear el Grid y asignárselo a una ventana para poder visualizarlo.
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
new Ext.grid.RowNumberer(),
{header:'City', dataIndex:'city',sortable: true},
{header:'Visits', dataIndex:'visits',sortable: true},
{header:'Page/Visits', dataIndex:'pageVisits',sortable: true},
{header:'Average Time', dataIndex:'averageTime', width:150,sortable: true}
],
border: false,
stripeRows: true
});
var win = new Ext.Window({
title: 'Grid example',
layout: 'fit',
width: 510,
height:350,
items: grid
});
win.show();
El código anterior es muy semejante al del tutorial anterior, lo único que hace es crear la tabla con las columnas necesarias y relacionar las columnas con los campos en el registro del store.
Creación de una tabla
Crear el PaggingToolbar
Vamos a crear la barra de paginación de la siguiente manera:
var pager = new Ext.PagingToolbar({
store: store, // <--grid and PagingToolbar using same store (required)
displayInfo: true,
displayMsg: '{0} - {1} of {2} Cities',
emptyMsg: 'No cities to display',
pageSize: 5
});
He configurado las propiedades más importantes, pero la única propiedad requerida es “store” el cual debe ser el mismo que se usa para la tabla.
“displayInfo” (boolean): Define si se despliega información en la parte derecha del componente sobre el estado de la paginación, por defecto es “false”.
“displayMsg” (string): Especifica el mensaje que se desea desplegar cuando la propiedad anterior (“displayInfo”) es seleccionada “true”, el mensaje por defecto es “Displaying {0} – {1} of {2}”, en este caso lo hemos cambiado, es importante notar que {0} será remplazado por el parámetro “start”, {1} se remplazará por “star + limit” y {2} se remplazará por “totalProperty”.
“emptyMsg” (string): Este mensaje se mostrará cuando el servidor no regrese ningún registro, si no la configuramos mostrará “No data to display” por defecto.
“pageSize” (number) : Aquí definimos el número de registros por página, en este caso le asignamos cinco, pero queda a criterio del desarrollador, solamente se debe tener en cuenta que a mayor registros por página más difícil será para el usuario encontrar lo que necesita, por defecto la configuración de esta propiedad es 20.
Asignar la barra de paginación al Grid
Una vez que hemos creado nuestra barra de paginación se la podemos asignar al grid en la barra superior (tbar) o inferior (bbar), en este caso se la voy asignar en la parte inferior de la siguiente manera:
var grid = new Ext.grid.GridPanel({
store: store, // <--El grid y PagingToolbar usan el mismo store
columns: [
new Ext.grid.RowNumberer(),
{header:'City', dataIndex:'city',sortable: true},
{header:'Visits', dataIndex:'visits',sortable: true},
{header:'Page/Visits', dataIndex:'pageVisits',sortable: true},
{header:'Average Time', dataIndex:'averageTime', width:150,sortable: true}
],
bbar: pager, // <--- Barra de paginación
border: false,
stripeRows: true
});
Barra de paginación
El componente “Ext.PagingToolbar” se encarga de controlar la navegación entre las páginas, cuenta con botones para avanzar/retroceder página por página o avanzar hasta el final/inicio.
Enviar parámetros extra
Si en cada petición necesitamos mandar parámetros extra al servidor, podemos definirle al “store” la propiedad “baseParams” la cual recibe un objeto de la siguiente manera:
var store = new Ext.data.JsonStore({
url: 'paging.php',
root: 'data',
totalProperty: 'total',
fields: ['city','visits','pageVisits','averageTime'],
baseParams: {x:10,y:20} //<--- parámetros definidos
});
Al paginar la información automáticamente se mandarán los parámetros definidos en el código anterior, recordemos que estos parámetros normalmente nunca cambian.
Existen situaciones en las que necesitamos enviar un parámetro “z” en algún momento en específico o necesitamos modificar este parámetro con diferentes valores, por lo tanto se los mandamos cuando hacemos el “load” del store:
//parámetros variables
store.load({params:{z:10});
Error NaN en la barra de paginación
Al parecer esto nos resuelve el problema fácilmente, pero cuando actualizamos el explorador nos damos cuenta que aparecen algunos “NaN” en la barra de paginación en lugar de aparecer los números correctos, este error es muy común y sucede porque el componente no puede calcular la página en la que se encuentra, para resolverlo solamente necesitamos enviar los parámetros “start” y “limit” junto con el parámetro “z”.
//resolviendo el NaN
store.load({params:{z:10,start:0,limit:5}});
Error NaN solucionado
Hemos resuelto el problema del NaN, pero ahora cada vez que paginamos el parámetro “z” se está perdiendo, para solucionar esto podemos utilizar un evento (“beforechange”) el cual se dispara antes de que el componente cambie de página, es decir antes de que se haga la llamada por medio de Ajax al servidor, este evento es el que necesitamos, porque aquí podemos agregar los parámetros que necesitemos, en este caso el parámetro “z”.
pager.on('beforechange',function(bar,params){
params.z = 30;
});
Con esto es suficiente para que el parámetro “z” se envíe en cada cambio de página.
Conclusiones
En este tema vimos como mostrar mucha información en partes, este componente es muy fácil de utilizar y sobretodo muy flexible, espero el funcionamiento haya quedado claro, si tienes dudas puedes inscribirte en el foro para poder platicar mejor, de igual forma puedes seguirnos en Twitter para estar actualizado en los nuevos tutoriales que vamos sacando.





Commercial ExtJs and Sencha Touch Themes


Un ejemplo muy claro de uso de la paginación.
Yo os hago un pequeño apunte por si a alguien le pasa que limit y start no pueden ser usados como variables en el lenguaje del servidor. Yo tuve un problema de este tipo que solucioné con paramNames (en versión 3 se usa en el store en la 2 se usaba en el pagingToolbar) este parametro de configuración te permite renombrar start y limit de forma transparente al componente para que sean enviados al servidor con otro nombre.