【问题标题】:DataTables sorts strings instead of numericDataTables 对字符串而不是数字进行排序
【发布时间】:2012-07-05 16:24:01
【问题描述】:

我正在使用jquery.datatables 在数据表列中显示数字。数字被格式化为在千单位之间有空格(如123 456 789)。不幸的是,这种数字格式会引发 string 排序而不是 number 排序(请参阅本问题末尾的屏幕截图)。

我已经确定:

  • 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知识很差,这里最好的方法是什么?

  1. 调整字符串排序函数以检测 格式化数以千计 的情况,并进行比较(我猜这在大型数据集上会很慢)。
  2. 提供专用于千位格式的数字排序功能?在这种情况下
    • 您将如何编码?
    • 如何向核心排序功能指示使用这个特殊的数字排序功能?

这是排序现在的样子:

【问题讨论】:

    标签: jquery sorting datatables


    【解决方案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));
    

    使用合理数量的值,这将足够快。如果您没有检测到性能问题,则不应尝试丰富数据。

    编辑:

    其实the documentation提出了一个合适的(类似的)排序函数:

    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

    【讨论】:

    • 太棒了!但是我怎么能强制 _fnSort() 对相关列使用这个排序函数呢?
    • 这里是 DataTables 的作者 - 很好的答案 - 投了赞成票。我建议标记为正确/接受:-)。唯一的错字是 sType 作为大写的“T”:datatables.net/ref#sType。还值得指出的是,还有很多其他的排序插件(有些具有类型检测功能)-datatables.net/plug-ins/sorting
    • 嗨。抱歉打错了,现已修正。
    • 太棒了!今天下午我会试试这个,然后告诉你:)
    • 好吧,我偶然发现了另一个问题:如何“设置我的列的 sType”。我可以在文档“如何使用 DataTables 插件排序函数(基于类型)”部分中看到 javascript 代码。如果我在我的 html 中定义了大量的 dataTable,我该如何使用这个 javascript 代码?理想情况下,我会想象像 XX
    【解决方案2】:

    好的,经过大量搜索,我找到了替代解决方案。 dystroyAllan Jardine 提出的解决方案当然更干净。但这意味着触摸 HTML 和在my case 中,触摸 HTML 会引发像下面这样一个棘手的消息框。

    所以我的解决方案是触摸 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,你会发现他们有一个函数可以确定每列值的类型并捕获格式

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-23
          • 1970-01-01
          • 2011-06-14
          • 2013-06-05
          相关资源
          最近更新 更多