【问题标题】:Add number range filter to multiple DataTable columns将数字范围过滤器添加到多个 DataTable 列
【发布时间】:2020-11-11 01:05:18
【问题描述】:

我有一个 DataTable,我正在尝试向其中的多个列添加过滤器。有些列是字符串,需要文本输入,而其他列是数字,需要范围输入。我将过滤器添加到每一列as described here。对于范围输入,我正在尝试添加我自己的自定义搜索插件as described here。本质上,我正在尝试结合文档的两个部分的策略:我想遍历应用过滤器的每一列,对于那些数字列,我想使用范围过滤器。他们在多列过滤文档中提供的示例表包括数字列,但他们用于这些列的过滤器是文本输入,坦率地说,这似乎不像大多数人在现实世界的实现中会采用的方式。他们提供的用于设置数值范围过滤器的文档包括一个示例,该示例只有一列要被输入过滤,这允许他们将适当的列索引硬编码到他们的自定义函数中。

我的问题是我不知道如何将我需要的变量放入自定义范围过滤器函数中。具体来说,我需要获取列索引和用户输入到函数中。我将this bootstrap slider 用于范围输入,因此为了获取用户输入值,我在我的输入上调用.slider 并传入'getValue'

如何将我的变量,特别是列索引和用户输入,放入我的自定义范围过滤器函数中?

我的代码如下。我还制作了这个JSFiddle,它显示了我正在尝试做的事情。如果您注释掉自定义 DataTables 函数,请注意两个文本输入的工作方式。

function populateEntryTable() {
    $('#entryTableContainer').empty();
    /* put demo data in array of objects that is used to populate DataTable */
    var entries = [{name: John, age: 20, salary: 40000},
     {name: Bill, age: 40, salary: 200000},
     {name: Amy, age: 31, salary: 150000}];

    /*build my table*/
    $('#entryTableContainer').append('<table id="entryTable"><thead><tr></tr></thead><tbody></tbody></table>');
    for (var key in entries[0]) {
        $('#entryTableContainer thead tr').append('<th>' + key + '</th>');
    }
    for (var i = entries.length - 1; i >= 0; i--) {
        for (var key in entries[i]) {
            $('#entryTableContainer tbody tr:last-child').append('<td>' + entries[i][key] + '</td>');
        }
    }

    /* add column filters below each column, as described in DataTables documentation */
    $('#entryTable thead tr').clone(true).appendTo('#entryTable thead');
    var numberInputs = ['age','salary'];
    $('#entryTable thead tr:eq(1) th').each(function(i) {
        var title = $(this).text();
            /* if the col requires a text input filter, do text input filter stuff, which works fine. Else if it requires a number range filter, do number filter stuff, which doesn't work fine. */
            if (numberInputs.indexOf(title) == -1) {
              $(this).html('<input type="text" placeholder="Search">');
              $('input',this).on('keyup change',function() {
                if (entryTable.column(i).search() !== this.value) {
                    entryTable.column(i).search(this.value).draw();
                }
            });
        } else if (numberInputs.indexOf(title) > -1) {
        /* get min and max values in each column to set appropriate bootstrap-slider attributes */
            var min;
            var max;
            $('#entryTable tbody tr').each(function(j) {
                var item = parseFloat($('#entryTable tbody tr:eq(' + j + ') td:eq(' + i + ')').text());
                if (min == undefined || item < min) {
                    min = Math.floor(item);
                }
                if (max == undefined || item > max) {
                    max = Math.ceil(item);
                }
            });
        
        /* create bootstrap-slider with double inputs */
            $(this).html('<input id="' + title + '" data-slider-min="' + min + '" data-slider-max="' + max + '" data-slider-step="1" data-slider-value="[' + min + ',' + max + ']">');
            $('#' + title).slider({});
        
        /* add listener for bootstrap-slider change */
            $('input',this).on('change',function() {
            /* returns an array with the min and max user inputs*/
               var userInputs = $(this).slider('getValue');
               var userMin = userInputs[0];
               var userMax = userInputs[1];
               entryTable.draw();
            });
        }
    });

    /* call DataTable on my table and include my option settings*/
    var entryTable = $('#entryTable').DataTable({
        orderCellsTop: true,
        paging: false,
        bInfo: false,
        scrollY: 400,
        scrollCollapse: true,
        order: [ 1, 'desc' ],
        searching: true
    });

    /* searching must be set to true for my column searches to work, but I don't want the whole table search bar to display, so I remove it here */
    $('#entryTable_filter').addClass('d-none');
}

// custom DataTables function for filtering number ranges
$.fn.dataTable.ext.search.push(
    function( settings, data, dataIndex ) {
        /* how do I get i (the col index of the filter that the user is engaging with), the userMin and the userMax into here??? */
        var colVal = parseFloat(data[i].replace('$','')) || 0;
 
        if ( ( isNaN( userMin ) && isNaN( userMax ) ) ||
             ( isNaN( userMin ) && colVal <= userMax ) ||
             ( userMin <= colVal   && isNaN( userMax ) ) ||
             ( userMin <= colVal   && colVal <= userMax ) )
        {
            return true;
        }
        return false;
    }
);

【问题讨论】:

    标签: javascript jquery datatables bootstrap-slider


    【解决方案1】:

    我能够通过在 .each 循环中移动自定义函数来解决我的问题,将我需要的变量带入适当的范围。我把我的解决方案放在JSFiddle

        $(function() {
      populateEntryTable()
    
      function populateEntryTable() {
        $('#entryTableContainer').empty();
        /* put demo data in array of objects that is used to populate DataTable */
        var entries = [{
            name: 'John',
            title: 'Coordinator',
            age: 20,
            salary: 40000
          },
          {
            name: 'Bill',
            title: 'Manager',
            age: 40,
            salary: 200000
          },
          {
            name: 'Amy',
            title: 'Manager',
            age: 31,
            salary: 150000
          }
        ];
    
        /*build my table*/
        $('#entryTableContainer').append('<table id="entryTable"><thead><tr></tr></thead><tbody></tbody></table>');
        for (var key in entries[0]) {
          $('#entryTable thead tr').append('<th>' + key + '</th>');
        }
        for (var i = entries.length - 1; i >= 0; i--) {
          $('#entryTable tbody').append('<tr></tr>');
          for (var key in entries[i]) {
            $('#entryTable tbody tr:last-child').append('<td>' + entries[i][key] + '</td>');
          }
        }
    
        $('#entryTable thead tr').clone(true).appendTo('#entryTable thead');
        var numberInputs = ['age', 'salary'];
        $('#entryTable thead tr:eq(1) th').each(function(i) {
          var title = $(this).text();
          // if the col requires a text input filter, do text input filter stuff, which works fine. Else if it requires a number range filter, do number filter stuff, which doesn't work fine.
          if (numberInputs.indexOf(title) == -1) {
            $(this).html('<input type="text" placeholder="Search">');
            $('input', this).on('keyup change', function() {
              if (entryTable.column(i).search() !== this.value) {
                entryTable.column(i).search(this.value).draw();
              }
            });
          } else if (numberInputs.indexOf(title) > -1) {
            // get min and max values in each column to set appropriate bootstrap-slider attributes
            var min;
            var max;
            $('#entryTable tbody tr').each(function(j) {
              var item = parseFloat($('#entryTable tbody tr:eq(' + j + ') td:eq(' + i + ')').text());
              if (min == undefined || item < min) {
                min = Math.floor(item);
              }
              if (max == undefined || item > max) {
                max = Math.ceil(item);
              }
            });
    
            var rangeMax = title == 'age' ? 100 : 1000000;
            var step = rangeMax == 100 ? 1 : 10000;
            $(this).html('<input id="' + title + '" type="range" value="0" min="0" max="' + rangeMax + '" step="' + step + '">');
            var userInput = $('input', this).val();
    
            // custom DataTables function for filtering number ranges
            $.fn.dataTable.ext.search.push(
              function(settings, data, dataIndex) {
                var colVal = parseFloat(data[i]) || 0;
                if (colVal > userInput) {
                  return true;
                }
                return false;
              }
            );
    
            // add listener for bootstrap-slider change
            $('input', this).on('change', function() {
              userInput = $(this).val();
              entryTable.draw();
            });
          }
        });
        /* call DataTable on my table and include my option settings */
        var entryTable = $('#entryTable').DataTable({
          orderCellsTop: true,
          paging: false,
          bInfo: false,
          scrollY: 400,
          scrollCollapse: true,
          order: [1, 'desc'],
          searching: true
        });
        /*     hide whole table search bar--cannot set 'searching' to false because this also disables individual column search capabilities */
        $('#entryTable_filter').hide();
      }
    });
    

    【讨论】:

      猜你喜欢
      • 2022-08-04
      • 1970-01-01
      • 2011-10-21
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多