【问题标题】:DataTables+Datepicker filter table by date rangeDataTables+Datepicker 按日期范围过滤表格
【发布时间】:2019-07-08 13:38:59
【问题描述】:

尝试使用两个有界日期选择器按日期范围实现 DataTables 过滤器。

我在 SO 上看到的类似问题很少,但没有一个对我有用。

到目前为止,我设法实现了界面元素,但不知道如何将它们组合在一起以进一步进行。任何帮助表示赞赏。

var myTableData = 
  [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "$320,800",
      "start_date": "2011/04/25",
      "office": "Edinburgh",
      "extn": "5421"
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "$170,750",
      "start_date": "2011/07/25",
      "office": "Tokyo",
      "extn": "8422"
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "salary": "$86,000",
      "start_date": "2009/01/12",
      "office": "San Francisco",
      "extn": "1562"
    },
    {
      "id": "4",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "$433,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    },
    {
      "id": "5",
      "name": "Airi Satou",
      "position": "Accountant",
      "salary": "$162,700",
      "start_date": "2008/11/28",
      "office": "Tokyo",
      "extn": "5407"
    },
    {
      "id": "6",
      "name": "Brielle Williamson",
      "position": "Integration Specialist",
      "salary": "$372,000",
      "start_date": "2012/12/02",
      "office": "New York",
      "extn": "4804"
    },
    {
      "id": "7",
      "name": "Herrod Chandler",
      "position": "Sales Assistant",
      "salary": "$137,500",
      "start_date": "2012/08/06",
      "office": "San Francisco",
      "extn": "9608"
    }
];

$('.datepicker').datepicker();

var myDataTable = $('#staff').DataTable({
  sDom: 't',
  data: myTableData,
  columns: [
    {title: 'Name', data: 'name'},
    {title: 'Position', data: 'position'},
    {title: 'Office', data: 'office'},
    {title: 'Hire date', data: 'start_date'},
    {title: 'Salary', data: 'salary'}
  ]
});
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="application/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
  </head>
  <body>
    <label>Start date:</label>
    <input id="startdate" class="datepicker"></input>
    <label>End date:</label>
    <input id="enddate" class="datepicker"></input>
    <button id="filter">Filter</button>
    <table id="staff"></table>
  </body>
</html>

【问题讨论】:

    标签: javascript jquery jquery-ui datatables datepicker


    【解决方案1】:

    我对您的代码做了一些修改。请参阅下面 JavaScript sn-p 中的 cmets,其中大部分位于底部,在您的 var myDataTable = $('#staff').DataTable() 声明下:

    // I changed some of the start_date values to be more recent, just for testing.
    var myTableData = [{
        "id": "1",
        "name": "Tiger Nixon",
        "position": "System Architect",
        "salary": "$320,800",
        "start_date": "2017/04/25",
        "office": "Edinburgh",
        "extn": "5421"
      },
      {
        "id": "2",
        "name": "Garrett Winters",
        "position": "Accountant",
        "salary": "$170,750",
        "start_date": "2018/07/25",
        "office": "Tokyo",
        "extn": "8422"
      },
      {
        "id": "3",
        "name": "Ashton Cox",
        "position": "Junior Technical Author",
        "salary": "$86,000",
        "start_date": "2019/01/12",
        "office": "San Francisco",
        "extn": "1562"
      },
      {
        "id": "4",
        "name": "Cedric Kelly",
        "position": "Senior Javascript Developer",
        "salary": "$433,060",
        "start_date": "2018/03/29",
        "office": "Edinburgh",
        "extn": "6224"
      },
      {
        "id": "5",
        "name": "Airi Satou",
        "position": "Accountant",
        "salary": "$162,700",
        "start_date": "2018/11/28",
        "office": "Tokyo",
        "extn": "5407"
      },
      {
        "id": "6",
        "name": "Brielle Williamson",
        "position": "Integration Specialist",
        "salary": "$372,000",
        "start_date": "2018/12/02",
        "office": "New York",
        "extn": "4804"
      },
      {
        "id": "7",
        "name": "Herrod Chandler",
        "position": "Sales Assistant",
        "salary": "$137,500",
        "start_date": "2018/08/06",
        "office": "San Francisco",
        "extn": "9608"
      }
    ];
    
    var myDataTable = $('#staff').DataTable({
      sDom: 't',
      data: myTableData,
      columns: [{
          title: 'Name',
          data: 'name'
        },
        {
          title: 'Position',
          data: 'position'
        },
        {
          title: 'Office',
          data: 'office'
        },
        {
          title: 'Hire date',
          data: 'start_date'
        },
        {
          title: 'Salary',
          data: 'salary'
        }
      ]
    });
    
    // I instantiate the two datepickers here, instead of all at once like before.
    // I also changed the dateFormat to match the format of the dates in the data table.
    $("#startdate").datepicker({
      "dateFormat": "yy/mm/dd",
      "onSelect": function(date) {  // This handler kicks off the filtering.
        minDateFilter = new Date(date).getTime();
        myDataTable.draw(); // Redraw the table with the filtered data.
      }
    }).keyup(function() {
      minDateFilter = new Date(this.value).getTime();
      myDataTable.draw();
    });
    
    $("#enddate").datepicker({
      "dateFormat": "yy/mm/dd",
      "onSelect": function(date) {
        maxDateFilter = new Date(date).getTime();
        myDataTable.draw();
      }
    }).keyup(function() {
      maxDateFilter = new Date(this.value).getTime();
      myDataTable.draw();
    });
    
    // The below code actually does the date filtering.
    minDateFilter = "";
    maxDateFilter = "";
    
    $.fn.dataTableExt.afnFiltering.push(
      function(oSettings, aData, iDataIndex) {
        if (typeof aData._date == 'undefined') {
          aData._date = new Date(aData[3]).getTime(); // Your date column is 3, hence aData[3].
        }
    
        if (minDateFilter && !isNaN(minDateFilter)) {
          if (aData._date < minDateFilter) {
            return false;
          }
        }
    
        if (maxDateFilter && !isNaN(maxDateFilter)) {
          if (aData._date > maxDateFilter) {
            return false;
          }
        }
    
        return true;
      }
    );
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="application/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    <label>Start date:</label>
    <input id="startdate" class="date_range_filter" />
    <label>End date:</label>
    <input id="enddate" class="date_range_filter" />
    <table id="staff"></table>

    我还删除了“过滤器”按钮,因为在此实现中不需要它。当您从日期选择器中选择一个日期时,表格应该会自动更新。

    【讨论】:

      【解决方案2】:

      您的(稍作修改)示例具有一定的附加值(独立于时区、有限的年份范围、有界的日期选择器):

      //Data definition
      var myTableData =
        [{
          "id": "1",
          "name": "Tiger Nixon",
          "position": "System Architect",
          "salary": "$320,800",
          "start_date": "2011/04/25",
          "office": "Edinburgh",
          "extn": "5421"
        }, {
          "id": "2",
          "name": "Garrett Winters",
          "position": "Accountant",
          "salary": "$170,750",
          "start_date": "2011/07/25",
          "office": "Tokyo",
          "extn": "8422"
        }, {
          "id": "3",
          "name": "Ashton Cox",
          "position": "Junior Technical Author",
          "salary": "$86,000",
          "start_date": "2009/01/12",
          "office": "San Francisco",
          "extn": "1562"
        }, {
          "id": "4",
          "name": "Cedric Kelly",
          "position": "Senior Javascript Developer",
          "salary": "$433,060",
          "start_date": "2012/03/29",
          "office": "Edinburgh",
          "extn": "6224"
        }, {
          "id": "5",
          "name": "Airi Satou",
          "position": "Accountant",
          "salary": "$162,700",
          "start_date": "2008/11/28",
          "office": "Tokyo",
          "extn": "5407"
        }, {
          "id": "6",
          "name": "Brielle Williamson",
          "position": "Integration Specialist",
          "salary": "$372,000",
          "start_date": "2012/12/02",
          "office": "New York",
          "extn": "4804"
        }, {
          "id": "7",
          "name": "Herrod Chandler",
          "position": "Sales Assistant",
          "salary": "$137,500",
          "start_date": "2012/08/06",
          "office": "San Francisco",
          "extn": "9608"
        }
      ];
      //Global variable for future use
      var datepickers = [{
          id: 'startdate',
          coid: 'enddate',
          value: null,
          limiter: 'minDate'
        }, {
          id: 'enddate',
          coid: 'startdate',
          value: null,
          limiter: 'maxDate'
        }
      ];
      //Translate 'yy/mm/dd' string to UTC date
      const yymmddUTC = str => new Date(...str.split('/').map((value,index) => index == 1 ? value-- : value));
      //DataTables object definition
      var myDataTable = $('#staff').DataTable({
          sDom: 't',
          data: myTableData,
          columns: [{
              title: 'Name',
              data: 'name'
            }, {
              title: 'Position',
              data: 'position'
            }, {
              title: 'Office',
              data: 'office'
            }, {
              title: 'Hire date',
              data: 'start_date'
            }, {
              title: 'Salary',
              data: 'salary'
            }
          ]
        });
      //Limit datepicker options to those valid for current dataset
      var dates = myDataTable.column(3).data().unique().sort();
      var minDate = dates[0];
      var maxDate = dates[dates.length-1];
      //datepicker objects definition
      $('.datepicker').datepicker({
        dateFormat: 'yy/mm/dd',
        changeMonth: true,
        defaultDate: minDate,
        changeYear: true,
        yearRange: minDate.substr(0,4)+':'+maxDate.substr(0,4),
        onSelect: function (selectedDate) {
          let datepicker = datepickers.find(entry => entry.id == $(this).attr('id'));
          $(`#${datepicker.coid}`).datepicker('option', datepicker.limiter, selectedDate);
          datepicker.value = yymmddUTC(selectedDate);
          myDataTable.draw();
        }
      }).on('change', function(){
        datepickers[datepickers.findIndex(item => item.id == $(this).attr('id'))].value = yymmddUTC($(this).val());
        myDataTable.draw();
      });
      //External search function
      $.fn.DataTable.ext.search.push((settings, row) => {
        let rowDate = yymmddUTC(row[3]);
        return (rowDate >= datepickers[0].value || datepickers[0].value == null) && (rowDate <= datepickers[1].value || datepickers[1].value == null);
      });
      <!doctype html>
      <html>
        <head>
          <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
          <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
          <script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
          <script type="application/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
          <script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
        </head>
        <body>
          <label>Start date:</label>
          <input id="startdate" class="datepicker"></input>
          <label>End date:</label>
          <input id="enddate" class="datepicker"></input>
          <table id="staff"></table>
        </body>
      </html>

      【讨论】:

      • 如果日期在数据表中为yyyy-mm-dd h:i:s 格式,我需要仅使用yyyy-mm-dd 进行搜索,而在数据表中显示格式为yyyy-mm-dd h:i:s 时如何执行此操作?任何建议都会有很大帮助。提前致谢。 @Curr195
      • 我省略了 yymmddUTC 函数的使用,并使用@AndroidNoobie 的方法来获取时间格式与getTime() 代替您的日期过滤,因为我的日期时间为yy-mm-dd h:i:s 格式我遇到了一些困难无论如何,一开始@Cur195 和@AndroidNoobie 的回答都有助于完成工作。非常感谢
      • 有一件事,在 chrome 中,日期选择器的输入字段显示以前选择的日期,如下拉列表,这很烦人,有什么提示可以解决这个问题吗?另外,我如何在过滤一次后取消选择日期并返回上一个完整列表? (对不起,如果这很烦人,但如果这与这个答案无关,会发布一个不同的问题。)
      【解决方案3】:

      您必须添加此代码部分以获取日期范围和雇用日期。

          $(document).ready(function(){
           $.fn.dataTable.ext.search.push(
           function (settings, data, dataIndex) {
              var min = $('#startdate').datepicker("getDate");
              var max = $('#enddate').datepicker("getDate");
              var hireDate = new Date(data[3]);
              if (min == null && max == null) { return true; }
              if (min == null && hireDate <= max) { return true;}
              if(max == null && hireDate >= min) {return true;}
              if (hireDate <= max && hireDate >= min) { return true; }
              return false;
          }
          );
          });
      

      而且你必须为你的按钮点击事件。

      $("#filter").click(function () {
      
          var myDataTable = $('#staff').DataTable();
              myDataTable.draw();
      });
      

      第一部分获取日期,第二部分再次绘制数据表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-25
        • 2018-06-19
        相关资源
        最近更新 更多