domingo, 21 de junio de 2015

SlickGrid. DataView (y IV) - Paginación

Artículos anteriores:

El objeto DataView provee también soporte para paginación en cliente, es decir si, como en nuestro ejemplo, tenemos el conjunto de datos completo descargado en cliente.

Para gestionar la paginación el objeto DataView dispone de dos métodos

  • getPagingInfo(): método que devuelve el estado actual de la paginación. Devuelve un objeto con cuatro propiedades:
    • pageSize: número de filas por página
    • pageNum: número de página actual. Es un índice basado en cero, es decir la primera página tiene un pageNum igual a cero.
    • totalRows: número total de filas del grid, sumando las de todas las páginas.
    • totalPages: número total de páginas. La última página se correspondería con un pageNum igual a totalPages menos uno.
  • setPagingOptions(args): método que establece las opciones de paginación. Recibe un objeto que puede tener dos propiedades:
    • pageSize: establece un nuevo tamaño de página (número de filas a mostrar por página). Si pageSize es cero todas las filas se muestran en una única página.
    • pageNum: establece la página actual. Un valor de 0 desplaza el grid a la primera página, mientras que un valor de (getPagingInfo().totalPages - 1) desplazará el grid a la última página.

y un evento:

  • onPagingInfoChanged: que se lanza cada vez que cambia el estado actual de paginación, ya sea porque se cambian las opciones o se cambia la página actual.

Para activar la paginación en nuestro ejemplo voy a incluir unos controles de opción para poder cambiar entre varios tamaños de página: una opción para mostrar todas las filas en una única página y otras 3 para establecer respectivamente 25, 50 ó 100 filas por página. También voy a añadir dos botones que nos permitan movernos a las páginas anterior y siguiente.

En el evento click de los controles de opción llamo al método setPagingOptions para establecer el tamaño de página seleccionado y desplazar el grid a la primer página (página cero).

En el evento click del botón de página anterior, recupero la pagina actual a partir de la información devuelta por el método getPagingInfo y, si la actual no es la primera, establezco como página activa la anterior a la actual a través del método setPagingOptions. Igualmente en el botón de página siguiente establezco la página activa a la siguiente si no se encuentra ya en la última página.

<div id="DataViewGrid" style="width:1024px; height:500px;"></div>
<div style="padding:10px">
 Filtro: Precio mínimo <span id="minCost">0</span><br />
 <input id="costFilter" type="range" min="0" max="2500" step="10" value="0" />
</div>
<div id="pager" style="padding:10px">
 Elementos por página:
 <input type="radio" name="pagesize" value="0" checked /> Todos
 <input type="radio" name="pagesize" value="25" /> 25
 <input type="radio" name="pagesize" value="50" /> 50
 <input type="radio" name="pagesize" value="100" /> 100<br />
 <button id="btnPrevious">&lt;</button>
 <button id="btnNext">&gt;</button>
</div>
$("[name=pagesize]").click(function () {
 dataProvider.setPagingOptions(
  { pageSize: parseInt($("[name=pagesize]:checked").val())
   , pageNum: 0 });
});

$("#btnPrevious").click(function () {
 var toPage = dataProvider.getPagingInfo().pageNum - 1;
 if (toPage < 0) toPage = 0;
 dataProvider.setPagingOptions({ pageNum: toPage });
});

$("#btnNext").click(function () {
 var toPage = dataProvider.getPagingInfo().pageNum + 1;
 var total = dataProvider.getPagingInfo().totalPages;
 if (toPage >= total) toPage = total - 1;
 dataProvider.setPagingOptions({ pageNum: toPage });
})

Si volvemos a cargar la página en el navegador podremos comprobar cómo podemos cambiar el tamaño de página con los controles de opción y movernos entre las diferentes páginas con los botones anterior y siguiente.

Incluir un paginador

El paginador de ejemplo SlickGridPager

Como en otras ocasiones, en el caso del paginador también podemos encontrar un paginador de ejemplo en el paquete de descarga del SlickGrid. Aunque es difícil que este paginador se ajuste completamente a las necesidades de nuestro proyecto sí que puede resultar muy útil como ejemplo o como base para nuestras propias implementaciones.

El paginador se encuentra en la carpeta controls del paquete de descarga y está compuesto por un archivo js (slick.pager.js) que encapsula la funcionalidad y una hoja de estilos css (slick.pager.css).
Para mostrar cómo podemos utilizar este paginador he añadido ambos archivos al sitio web de pruebas (slick.pager.js en la carpeta scripts y slick.pager.css en la carpeta css) y he añadido las referencias correspondientes en la página DataView.html.

Para crear el paginador simplemente tenemos que llamar al constructor que se encuentra disponible en Slick.Controls.Pager. El constructor precisa de tres parámetros: la instancia del DataView, la instancia del SlickGrid y un elemento jQuery que sirva de contenedor para el control de paginación.

Así que he creado un nuevo elemento div debajo del grid con id SlickPager para albergar el control de paginación.

    <link href="css/slick.pager.css" rel="stylesheet" />
    <link href="css/pildorasgrid.css" rel="stylesheet" />
    <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <script src="Scripts/jquery.event.drag-2.2.js"></script>
    <script src="Scripts/slick.core.js"></script>
    <script src="Scripts/slick.grid.js"></script>
    <script src="Scripts/gridformatters.js"></script>
    <script src="Scripts/grideditors.js"></script>
    <script src="data/productdatasource.js"></script>
    <script src="Scripts/slick.dataview.js"></script>
    <script src="Scripts/slick.pager.js"></script>

 
.....


    <div id="DataViewGrid" style="width:1024px; height:500px;"></div>
    <div id="SlickPager" style="width:1024px;"></div>
    <div style="padding:10px">
        Filtro: Precio mínimo <span id="minCost">0</span><br />
        <input id="costFilter" type="range" min="0" max="2500" step="10" value="0" />
    </div>
    <div id="pager" style="padding:10px">
        Elementos por página:
        <input type="radio" name="pagesize" value="0" checked /> Todos
        <input type="radio" name="pagesize" value="25" /> 25
        <input type="radio" name="pagesize" value="50" /> 50
        <input type="radio" name="pagesize" value="100" /> 100<br />
        <button id="btnPrevious">&lt;</button>
        <button id="btnNext">&gt;</button>
    </div>

 
.....

var pager = new Slick.Controls.Pager(dataProvider, grid, $("#SlickPager"));

Si volvemos a cargar la página comprobaremos que ahora disponemos de dos paginadores (el nuevo bastante más completo y elegante que el mío pero creo que, a pesar de ser bastante "cutre", ha cumplido su función).

Grid con los dos paginadores

El evento onPagingInfoChanged

Si nos fijamos en el funcionamiento de los paginadores podemos observar que la información del paginador de ejemplo se actualiza independientemente de cual utilicemos. Sin embargo cuando utilizamos este paginador la información del nuestro no se actualiza.

El motivo es que nuestro paginador no está detectando los cambios en la información de paginación del grid. Para poder detectarlos y reaccionar ante ellos actualizando la información correspondiente deberemos suscribirnos al evento onPagingInfoChanged del DataView.

dataProvider.onPagingInfoChanged.subscribe(function (e, pagingInfo) {
 $("[name=pagesize]").each(function () {
  var radio = $(this);
  radio.prop("checked"
   , pagingInfo.pageSize == parseInt(radio.val()));
 });
});

Si volvemos a cargar la página comprobaremos que, al cambiar el tamaño de página desde el nuevo paginador, los controles de selección del nuestro se actualizan con el nuevo valor.

El código

Puedes descargar el código de todos los ejemplos de SlickGrid de:


No hay comentarios:

Publicar un comentario