DataTables сортирует строки вместо числовых
Я использую jquery.datatables, чтобы отображать числа в столбцах datatables. Числа отформатированы так, чтобы иметь место между тысячами единиц (например, 123 456 789
). К сожалению, это числовое форматирование провоцирует сортировку строк вместо сортировки по номерам (см. Скриншот в конце этого вопроса).
Я определил, что:
-
function _fnSort(oSettings, bApplyClasses) {
- основная функция для сортировки.
- В этой функции используется подход сортировки динамических функций (тот, который выполняется, если
if (!window.runtime) {
истинно)
-
Используемые функции сортировки строк - это две следующие функции.
/*
* 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));
},
Мои знания в javascript довольно бедны, какой был бы лучший подход здесь?
- Измените функцию сортировки строк, чтобы определить число, отформатированное в тысячах случаев, и выполните сравнение (я думаю, это было бы довольно медленно при большом наборе данных).
- Предоставить числовую функцию сортировки, предназначенную для форматирования чисел тысяч? В таком случае
- как бы вы это кодировали?
- Как я могу указать на функцию сортировки ядра, чтобы использовать эту специальную функцию цифровой сортировки?
Вот как выглядит сортировка:
![enter image description here]()
Ответы
Ответ 1
Чтобы отсортировать этот тип значений, вы можете использовать эту функцию сортировки:
var sortFunction=function(a, b){
var ia = parseInt(a.split(' ').join(''), 10);
var ib = parseInt(b.split(' ').join(''), 10);
return ia-ib;
};
Тест:
var data = ['3 333', '100 333', '22 000', '1 333'];
console.log(data.sort(sortFunction));
При разумном количестве значений это будет достаточно быстро. Вы не должны пытаться обогащать данные, если не обнаруживаете проблем с производительностью.
EDIT:
Фактически в документации предлагается соответствующая (аналогичная) сортировка:
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;
}
} );
После добавления этого расширения вам просто нужно установить sType
вашего столбца.
Ответ 2
Хорошо, после большого поиска я нашел альтернативные решения. Решение, предложенное dystroy и Allan Jardine, безусловно, чище. Но это касается касания HTML и моего дела, касаясь HTML-кода, вызванного сложным полем сообщений, как показано ниже.
![enter image description here]()
Итак, мое решение - просто коснуться строки сортировки javascript, сортировки, для переключения между числовыми и текстовыми случаями. Я бы хотел, чтобы это было чище, используя что-то вроде isDigit(sa.charAt[0])
, но оно просто не работает, несмотря на все мои попытки. По крайней мере, это решение работает и не подразумевает каких-либо заметных эксплуатационных затрат:
/*
* 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));
},
Ответ 3
Для тех, кто читает это и хочет получить полный ответ для пробела между цифрами:
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 }
],
});
}
Ответ 4
Просто установите десятичную точку при построении DataTable следующим образом:
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});
Если вы копаете больше в jquery.dataTables.js
, вы обнаружите, что у них есть функция, которая определяет тип каждого значения столбца и ловит формат