viernes, 19 de junio de 2015

SlickGrid. DataView (II). Ordenación simple y múltiple

Artículos anteriores:
Para habilitar la ordenación con el DataView deberemos seguir estos dos sencillos pasos:

  • Definir por qué columnas se va a poder ordenar el grid estableciendo la propiedad sortable de éstas a true en la definición de columnas.
  • Suscribirse al evento sort del SlickGrid con una función que llame a la ordenación del DataView. La ordenación del DataView se genera invocando el método sort que recibe dos parámetros:
    • comparer: una función comparadora que recibe como parámetros dos elementos de datos y devuelve 1 si el primero es mayor que el segundo o -1 en caso contrario
    • sortAsc: valor booleano que indica si la ordenación es ascendente

El evento de ordenación onSort del SlickGrid devuelve un objeto args que contiene, si no está habilitada la ordenación por múltiples columnas, dos propiedades que definen la ordenación a realizar:

  • sortCol: definición de la columna sobre la que se va a realizar la ordenación
  • sortAsc: valor booleano que indica si la ordenación es en orden ascendente



var columns = [
 { name: "ID", field: "ProductID", id: "ProductID", width: 60, resizable: false
  , headerCssClass: "prKeyHeadColumn", cssClass: "numericCell", editor: Slick.Editors.Text
  , sortable: true },
 { name: "Nº Producto", field: "ProductNumber", id: "ProductNumber", width: 120, resizable: false
  , headerCssClass: "headColumn", editor: Slick.Editors.Text
  , sortable: true },
 { name: "Denominación", field: "Name", id: "Name", width: 250, minWidth: 150, maxWidth: 400
  , headerCssClass: "headColumn", editor: Slick.Editors.Text
  , sortable: true },
 { name: "Color", field: "Color", id: "Color", width: 80, minWidth: 60, maxWidth: 120
  , headerCssClass: "headColumn", formatter: Slick.Formatters.ColorFormatter
  , editor: Slick.Editors.Color },
 { name: "Precio", field: "StandardCost", id: "StandardCost", width: 110, minWidth: 80, maxWidth: 170
  , headerCssClass: "headColumn", cssClass: "numericCell", formatter: Slick.Formatters.CurrencyFormatter
  , editor: Slick.Editors.Text, sortable: true },
 { name: "Sub", field: "ProductSubcategoryID", id: "ProductSubcategoryID", width: 60, resizable: false
  , headerCssClass: "headColumn", cssClass: "numericCell", editor: subcategoryEditor
  , sortable: true },
 { name: "Subcategoría", field: "ProductSubcategoryID", id: "SubcategoryName"
  , width: 200, minWidth: 150, maxWidth: 400, headerCssClass: "headColumn"
  , formatter: asyncSubcategoryNameFormatter, asyncPostRender: getSubcategoryName, cache: {} }
];

.....


grid.onSort.subscribe(function (e, args) {
 var comparer = function (a, b) {
  return (a[args.sortCol.field] > b[args.sortCol.field]) ? 1 : -1;
 }
 dataProvider.sort(comparer, args.sortAsc);
});

He definido como "ordenables" las columnas ProductID, ProductNumber, Name, StandardCost y ProductSubcategoryID.
La función de comparación es muy simple, realiza una comparación con el operador "mayor que" del valor del campo en el elemento y devuelve el resultado.

Si cargamos la página en el navegador veremos que al hacer click en la cabecera de las columnas definidas como "ordenables" las filas del grid se reordenan en base a sus valores.

Ordenación del grid

Un tema a tener en cuenta en la ordenación es que la llamada al método sort del DataView genera una ordenación en el array original de datos que pasamos al DataView a través del método setItems(data).

Ordenación por múltiples columnas

Habilitar la ordenación por múltiples columnas es sencillo en el SlickGrid, basta con activar la propiedad multiColumnSort en el objeto de opciones del grid.

Si habilitamos la ordenación por múltiples columnas en el grid la información devuelta por el evento onSort cambia. En el controlador del evento onSort podemos saber si la ordenación es múltiple a través de la propiedad multiColumnSort del objeto args devuelto por el evento.

Si es una ordenación múltiple el objeto args define la ordenación a realizar a través de la propiedad sortCols. Esta propiedad contendrá un array de objetos con dos propiedades:

  • sortCol: con la definición de la columna por la que se ordena
  • sortAsc: valor que indica si la ordenación por esta columna es ascendente

Por lo tanto para habilitar la ordenación múltiple en el grid simplemente deberemos activar la propiedad multiColumnSort en las opciones del grid y modificar la función comparer para que realice la comparación de los elementos en función de las columnas definidas en la propiedad sortCols. En este caso la función comparer deberá tener en cuenta también si la ordenación de cada columna es ascendente o descendente.

var options = {
 editable: true,
 enableAsyncPostRender: true,
 asyncPostRenderDelay: 10,
 multiColumnSort: true
};


.....


grid.onSort.subscribe(function (e, args) {
 var comparer, ascending;
 if (args.multiColumnSort) {
  comparer = function (a, b) {
   var cols = args.sortCols;
   for (var i = 0, l = cols.length; i < l; i++) {
    var field = cols[i].sortCol.field;
    var sign = cols[i].sortAsc ? 1 : -1;
    var value1 = a[field], value2 = b[field];
    var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
    if (result != 0) {
     return result;
    }
   }
   return 0;
  };
 }
 else {
  comparer = function (a, b) {
   return (a[args.sortCol.field] > b[args.sortCol.field]) ? 1 : -1;
  };
  ascending = args.sortAsc;
 }
 dataProvider.sort(comparer, ascending);
});

Si recargamos la página en el navegador comprobaremos que ahora, además de poder ordenar los datos por las diferentes columnas, si ordenamos por una columna y, pulsando la tecla Mayúsculas (Shift), ordenamos por otra los datos se ordenan en base a la información de las dos columnas.

En la siguiente imagen se ve el grid ordenado por el ID de subcategoría en orden ascendente y, dentro de los elementos pertenecientes a la misma subcategoría, por precio en orden ascendente.

Ordenación múltiple

El código


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



Artículo siguiente:
SlickGrid. DataView (III) - Filtros de datos

No hay comentarios:

Publicar un comentario