2012-07-05 31 views
10

Estoy usando jquery.datatables para mostrar los números en las columnas de tablas de datos. Los números están formateados para tener espacios entre miles de unidades (como 123 456 789). Desafortunadamente, este formato de número provoca una clasificación de clasificación en lugar de un número clasificación (consulte la captura de pantalla al final de esta pregunta).DataTables ordena cadenas en lugar de numérico

He identificado que:

  • function _fnSort(oSettings, bApplyClasses) { es la función de núcleo para la clasificación.
  • En esta función, se utiliza el función dinámica de clasificación enfoque (el que ejecuta si if (!window.runtime) { es verdad)
  • las funciones de clasificación cadena utilizado son las dos funciones siguientes.

    /* 
    * text sorting 
    */ 
    "string-asc": function(a, b) { 
        var x = a.toLowerCase(); 
        var y = b.toLowerCase(); 
        return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 
    }, 
    
    "string-desc": function(a, b) { 
        var x = a.toLowerCase(); 
        var y = b.toLowerCase(); 
        return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 
    }, 
    

Mi conocimiento en javascript es bastante pobre, lo que sería el mejor enfoque aquí?

  1. ajustar la función de clasificación cadena para detectar el número miles formateados caso, y hacer la comparación (supongo que esto sería bastante lento en el conjunto de datos grande).
  2. Proporcione una función de clasificación numérica dedicada para número miles formateados? En ese caso
    • ¿cómo codificaría eso?
    • ¿Cómo podría indicar a la función de clasificación de núcleo, para utilizar esta función especial de clasificación numérica?

Esto es lo que el aspecto de clasificación, como por ahora:

enter image description here

Respuesta

10

Para ordenar este tipo de valores, puede utilizar esta función para ordenar:

var sortFunction=function(a, b)​{ 
    var ia = parseInt(a.split(' ').join(''), 10); 
    var ib = parseInt(b.split(' ').join(''), 10); 
    return ia-ib; 
}; 

prueba :

var data = ['3 333', '100 333', '22 000', '1 333']; 
console.log(data.sort(sortFunction)); 

Con una cantidad razonable de valores, esto será lo suficientemente rápido. No intente enriquecer los datos si no detecta problemas de rendimiento.

EDIT:

De hecho, the documentation propone un apropiado (similar) función de clasificación:

jQuery.extend(jQuery.fn.dataTableExt.oSort, { 
    "formatted_numbers-pre": function (a) { 
     a = (a==="-") ? 0 : a.replace(/[^\d\-\.]/g, ""); 
     return parseFloat(a); 
    }, 

    "formatted_numbers-asc": function (a, b) { 
     return a - b; 
    }, 

    "formatted_numbers-desc": function (a, b) { 
     return b - a; 
    } 
}); 

Después de haber añadido esta extensión, sólo hay que ajustar la sType de su columna.

+0

Awesome! Pero ¿cómo podría forzar a _fnSort() a utilizar esta función de clasificación para la columna en cuestión? –

+1

Ver edición (con enlace a la documentación). –

+2

Autor de DataTables aquí - buena respuesta - hasta votado. Sugeriría marcar como correcto/aceptado :-). Solo typo es sType como 'T' mayúscula: http://datatables.net/ref#sType. También vale la pena señalar que hay muchos otros plug-ins de clasificación (algunos con contrapartes de detección de tipo) - http://datatables.net/plug-ins/sorting –

0

Ok, después de mucha búsqueda, encontré soluciones alternativas.La solución propuesta por dystroy y Allan Jardine es ciertamente más limpia. Pero implica tocar el HTML y en my case, tocando el cuadro de mensaje complicado provocado por HTML como este a continuación.

enter image description here

Así que mi solución es simplemente tocar la cadena Javascript clasificar algo, para cambiar entre los casos numéricos y textuales. Ojalá pudiera ser más limpio usando algo como isDigit(sa.charAt[0]) pero simplemente no funciona a pesar de todos mis intentos. Al menos esta solución funciona y no implica ningún coste notable en el rendimiento:

/* 
    * text + integer sorting 
    */ 
    "string-asc": function(a, b) { 
     var sa = a.toString(); 
     if(sa.length > 0) { 
      // Don't know why, isDigit(sa.charAt[0]) doesn't work?? 
      var ca = sa.substring(0,1); 
      if(ca === "0" || ca === "1" || ca === "2" || ca === "3" || ca === "4" || ca === "5" || ca === "6" || ca === "7" || ca === "8" || ca === "9") { 
      var x1 = parseInt(a.split(' ').join(''), 10); 
      var y1 = parseInt(b.split(' ').join(''), 10); 
      return x1 - y1; 
      } 
     } 
     var x = a.toLowerCase(); 
     var y = b.toLowerCase(); 
     return ((x < y) ? -1 : ((x > y) ? 1 : 0)); 
    }, 

    "string-desc": function(a, b) { 
     var sa = a.toString(); 
     if(sa.length > 0) { 
      var ca = sa.substring(0,1); 
      if(ca === "0" || ca === "1" || ca === "2" || ca === "3" || ca === "4" || ca === "5" || ca === "6" || ca === "7" || ca === "8" || ca === "9") { 
       var x1 = parseInt(a.split(' ').join(''), 10); 
       var y1 = parseInt(b.split(' ').join(''), 10); 
       return y1 - x1; 
      } 
     } 
     var x = a.toLowerCase(); 
     var y = b.toLowerCase(); 
     return ((x < y) ? 1 : ((x > y) ? -1 : 0)); 
    }, 
0

Para cualquiera que esté leyendo esto y quiere que la respuesta completa para el espacio entre los números:

jQuery.extend(jQuery.fn.dataTableExt.oSort, { 
     "formatted_numbers-pre": function (a) { 
     a = (a===" ") ? 0 : a.replace(/[^\d\-\.]/g, ""); 
     return parseFloat(a); 
     }, 

     "formatted_numbers-asc": function (a, b) { 
     return a - b; 
     }, 

     "formatted_numbers-desc": function (a, b) { 
     return b - a; 
     } 
    }); 

    $('.myTable').DataTable({ 
     "columnDefs": [ 
     { "type": "formatted_numbers", "targets": 4 } 
     ], 
    }); 
    } 
0

Basta con establecer el punto decimal cuando la construcción de la DataTable como esto:

var main_table = $('#main_list').DataTable({ 
    ajax: { 
     url: "/api/your/data", 
     dataSrc: '' 
    }, 
    columns: [ 
     { data: "Col1" }, 
     { data: "Col2" }, 
     { data: "Col3" }, 
     { data: "Col4" } 
    ], 
    language: { 
     /* -----> */ "decimal": ",", // <--------- 
     "emptyTable": "Keine Daten in der Tabelle verfügbar", 
     "info": "Anzeigen von _START_ bis _END_ von _TOTAL_ Einträgen", 
     "infoEmpty": "Anzeigen von 0 bis 0 von 0 Einträgen", 
     "infoFiltered": "(filtriert von_MAX_ Gesamteinträge)", 
     "infoPostFix": "", 
     /* -----> */ "thousands": ".", // <--------- 
     "lengthMenu": "_MENU_ Einträge anzeigen", 
     "loadingRecords": "Laden...", 
     "processing": "Verarbeitung...", 
     "search": "Suche:", 
     "zeroRecords": "Keine passenden Datensätze gefunden", 
     "paginate": { 
      "first": "Erste", 
      "last": "Letzte", 
      "next": "Nächste", 
      "previous": "Vorherige" 
     }, 
     "aria": { 
      "sortAscending": ": aufsteigend sortieren", 
      "sortDescending": ": absteigend sortieren" 
     } 
    }, 
    columnDefs: [ 
     {//set german formatting 

      render: function (data, type, row) { 
       return formatDE(data,2); 
      }, 
      targets: [2, 4, 5] 
     }, 
     { 

      render: function (data, type, row) { 
       return formatDE(data,0); 
      }, 
      targets: [3] 
     } 
    ], 
    pageLength: 50}); 

Si se mira en más jquery.dataTables.js en que se encuentran que tienen una función que determina el tipo de cada columna valor y captura el formato

Cuestiones relacionadas