DataTables + Datepicker筛选器表按日期范围

时间:2019-02-14 13:46:10

标签: javascript jquery jquery-ui datatables datepicker

尝试使用两个有界日期选择器按日期范围实现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>

3 个答案:

答案 0 :(得分:3)

我对您的代码做了一些修改。请参见下面的JavaScript代码段中的注释,其中大部分位于您的String restApiUrl = System.getenv("REST_API_URL"); 声明的底部:

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;
  }
);

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

答案 1 :(得分: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>

答案 2 :(得分:0)

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

    $(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();
});

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