Twitter Facebook RSS Feed

lunes, 20 de octubre de 2008 a las 13:15hs por Dario Krapp

Hace unos días en un proyecto que estamos desarrollando con tecnología PHP 5.0 y MySql 5.0, viendo la documentación funcional descubrimos que teníamos una gran cantidad de formularios los cuales realizarían tareas de listado, altas, bajas y modificación de datos.
Entonces comenzamos por buscar una forma de automatizar las tareas que se realizarían frecuentemente, comenzamos con los listados, la aplicación contenía listados, donde una característica mínima que esperábamos de los mismos, era la posibilidad de paginación, para crear una experiencia de usuario aceptable y para no comprometer la performance de nuestro servidor de base de datos. De esta primera necesidad surgió la idea de reutilización de código y de encapsulamiento de toda la lógica de paginación. En este articulo comentamos como el uso de clases en PHP nos ayudó a resolver nuestro problema.

La intención que tuvimos fue la de crear una clase de paginación de forma de que en cada página donde se utilizara la clase, solo debiera definirse como se deseaba realizar el paginado y luego se le pidiera al objeto que mostrará el paginador y como es de suponerse, pudiera pedirsele el conjunto de registros correspondiente a la página seleccionada.
Nuestra clase, que llamamos pagedQuery quedo constituida por un constructor y algunos métodos, detallaremos que hace cada uno de ellos a continuación:

El constructor

El constructor toma los parámetros

p_uid
p_pagesize
p_cnn
p_table
p_preservepagenumber (opcional)
p_customSqlSentence (opcional)

Dónde:

p_uid es una cadena de texto con un nombre de identificación, este nombre interviene en los nombres e id’s de elementos HTML y código javascript que renderizará el paginador, por ejemplo si le pasamos un p_uid llamado «Usuarios» el objeto creará un input hidden llamado PgUsuarios y una función javascript llamada GTP_Usuarios para uso interno. De esta forma, si se desean ubicar varios paginadores dentro de una misma pagina PHP, simplemente hay que asignarle distintos p_uid’s y todo funcionará sin que un paginador interfiera con los otros.

p_pagesize indica la cantidad de registros por página que se mostrarán.

p_cnn espera una conexión a MySql para la toma de datos

p_table indica el nombre de la tabla de la cual se tomarán los datos a mostrar

p_preservepagenumber que es opcional y por defecto se encuentra establecido en verdadero, indica si se debe mantener el número de página en variables de sesión, una opción muy útil para mantener la página seleccionada aunque el usuario ingrese en otras páginas, un caso que se dará sin dudas en los listados editables (o sea en listados desde donde el usuario podrá crear, modificar y eliminar registros).

p_customSqlSentence que por defecto se encuentra establecido como un string vacio y es opcional, tiena la función de indicar que sentencia SQL se debe emplear como fuente de datos (por ejemplo si se debe emplear más de una tabla o si se desea ordenar por algún criterio), en tal caso se omitirá el parámetro p_table, una consideración que se debe tomar en cuenta es que en la consulta pasada en p_customSqlSentence el paginador siempre deberá insertar el comando LIMIT de MySql, a fin de paginar lo más eficientemente posible. por defecto el comando LIMIT es insertado al final de la sentencia SELECT pasada por el usuario, pero si por algún motivo se desea especificar dónde el comando LIMIT debe establecerse, deberá escribirse el texto {INSERT LIMIT HERE} dentro de la sentencia que el usuario establece en p_customSqlSentence para que el paginador haga el reemplazo correspondiente.

La tarea del constructor es guardar los parámetros pasados y recuperar el número de página, (o establecerlo si la página se carga por primera vez, en ese caso se establecerá en la primer página o en la que se indique en una variable interna de sesión ulilizada por la clase, si la opción p_preservepagenumber se ha establecido).

Un punto importante a considerar es que en el costructor se renderizan algunos elementos html y javascripts necesarios para el control del paginado, por lo que es imprescindible que el constructor sea invocado dentro del formulario <form> para que funcione correctamente.

Ejemplos:

$pagedDataset = new pagedQuery(‘Usuarios’, 20, $cnx, ‘tblUsuario’);

$pagedDataset = new pagedQuery(‘Usuarios’, 20, $cnx, », true, ‘SELECT nombre FROM tblUsuario WHERE idusuario > 100’ );

$pagedDataset = new pagedQuery(‘Usuarios’, 20, $cnx, », true, ‘SELECT nombre FROM tblUsuario WHERE idusuario > 100 {INSERT LIMIT HERE}’ );

El método getRecords

El método getrecords devolverá los registros correspondientes a la página seleccionada.

Ejemplo:

$DataSetUsu = $pagedDataset->getRecords();
$DataRowUsu = mysql_fetch_assoc($DataSetUsu);

El método renderPager

La invocación al método renderPager renderizará la porción de elementos html necesaria para poder efectuar el paginado.

Ejemplo:

$pagedDataset->renderPager();

El método getPageNumber

El método getPageNumber devolverá cual es el número de página seleccionado.

Ejemplo:

$SelectedPg = $pagedDataset->getSelectedPage();

El método getPageCount

El método getPageCount devolverá la cantidad de páginas totales

Ejemplo:

$Pages = $pagedDataset->getPageCount();

La propiedad (variable pública de la clase) CSSClass

La propiedad CSSClass Permite asignarle el nombre de un estilo deseado al paginador y también leerlo.

Para asignar los estilos adecuadamente hay que considerar la estructura del paginador renderizada, la cual se muestra a continuación:

<table class="pager">
<tr>
<td>
<input type="submit" value=" 1 " onclick="return GTP_paginador_adelanto(0);" />
</td>
<td>
<input type="submit" value="2" onclick="return GTP_paginador_adelanto(1);" />
</td>
<td>
<input type="submit" value="3" onclick="return GTP_paginador_adelanto(2);" />
</td>
<td>
<span>Pág. [1/3] - 6 Registros - viendo 2 registro(s) por página</span>
</td>
</tr>
</table>

Entonces si se desea modificar el estilo de los botones de las páginas una opcion válida es definir el estilo

.pager tr td input
{
font-size:20px;
}

otros ejemplos:

.pager
{
padding:10px;
}

.pager tr td
{
background-color:red;
}

.pager tr td input
{
font-size:20px;
}

pager tr td span
{
visibility: hidden;
}

Ejemplo:

$pagedDataset->CSSClass = 'pager';

si no se asigna ninguna clase de estilos, el paginador tomará por defecto el estilo Pager_ + p_uid, para nuestro ejemplo donde p_uid es «Usuarios» el paginador utilizará el estilo Pager_Usuarios por defecto.

Soporte en Javascript

La clase renderizará una serie de funciones javascript por si se desea interactuar con el paginado desde el cliente, todas las funciones javascript terminarán con el postfijo p_uid, Supongamos para nuestro ejemplo que nuestro p_uid es «Usuarios» entonces la clase
renderizará las funciones:

getPageNumberUsuarios, que permite conocer el número de página seleccionado del objeto con p_uid «Usuarios»

getPageCountUsuarios, que permite conocer el número total de páginas del objeto con p_uid «Usuarios»

goToPageUsuarios(número de página), provocará que la página se envié al servidor y vuelva al cliente en la página solicitada en la función del objeto con p_uid «Usuarios».

Esperamos que esta pequeña contribución les pueda ser de ayuda y a continuación dejaremos una página PHP con la clase y otra con algunos ejemplos

Para que el ejemplo pueda ejecutarse deberá crearse en MySql, en una base de datos que se desee, una tabla que deberá llamarse tblUsuario con dos campos VARCHAR, nombre y apellido y deberán establecerse los datos de la conexión en la página Ejemplos.php en a través de las variables $ej_hostname_cnx (nombre del servidor MySql), $ej_database_cnx (nombre de la base de datos), $ej_username_cnx(nombre de usuario) y $ej_password_cnx(clave del usuario) que se encuentran al principio de la página.

8 comentarios »

  1. ivan dice:

    Hola, muy pero muy bueno tú codigo, gracias por compartir 😀

  2. Derleth dice:

    me gusto mucho mucho mucho 🙂

  3. Leon dice:

    me gusto mucho, solo un pero deberia tener un link a una página demo no solo descarga.
    Gracias

  4. Jaime dice:

    Hola, está muy buena la clase y si, deberías poner un demo online, buscando por ahí también encotré esta otra clase, hechenle un ojo, a ver que les parece, se llama kpaginate, aquí está la paginación php.

  5. Miguel Angel dice:

    muy bueno, el post, pero esto es solo para mysql o se puede usar en otros gestores de BD, uso frecuentemente sqlserver 2000 y postgres, gracias

    • Dario Krapp dice:

      Hola Miguel,
      El código está desarrollado para funcionar con MySQL, para que funcione para otros motores deberías modificar la consulta SQL que genera el código PHP, ya que la sentencia que permite paginar varía con el motor. Creo que no vas a tener grandes diferencias con Postgres, lamentablemente el cambio va a ser más complejo con SQL Server 2000 (Ya que es una version de motor algo desactualizada).
      Suerte!

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.