【问题标题】:Multiple date range filters using jQuery DateRangePicker & Datatable使用 jQuery DateRangePicker 和 Datatable 的多个日期范围过滤器
【发布时间】:2026-01-01 00:50:02
【问题描述】:

我想做的是在 jQuery 数据表上创建多个不同类型的自定义过滤器。

this jsFiddle 中可以看到,我已经成功地创建了每列的输入框。有些是文本搜索,有些是日期范围。我已经让 jQuery daterangepicker 为那些具有类“日期过滤器”的输入框工作。如果您点击显示/隐藏列并选择“创建日期”或“更新日期”,您将看到日期选择器。

我创建了一个自定义过滤器来推送所选日期标准。 ($.fn.dataTableExt.afnFiltering.push(DateFilterFunction))。但是,过滤器无法按预期工作。我希望过滤器是累积的。如果您为一列选择日期范围(例如更新日期),然后为另一列选择日期范围(例如 DateCreated),过滤器似乎可以工作。但是,如果您更改第二个过滤器,则另一个过滤器将更改。此外,在清除日期范围列上的特定过滤器时,所有现有的日期范围列过滤器都会被删除。行为不稳定。

有人可以look at the code 解决问题吗?

   $(function () {


   $('#mytable thead tr.filters th').each(function () {
       var title = $(this).text();


       if ($(this).hasClass("input-filter")) {


           $(this).html('<input name ="' + $.trim(title).replace(/ /g, '') + '" type="text" class = "form-control" placeholder="Search ' + $.trim(title) + '" />');
       }
       else if ($(this).hasClass("date-filter")) {

           $(this).html('<div class="input-prepend input-group"><span class="add-on input-group-addon"><i class="glyphicon glyphicon-calendar fa fa-calendar"></i></span><input type="text" style="width: 200px" name="' + $.trim(title).replace(/ /g, '') + '"  placeholder="Search ' + $.trim(title) + '" class="form-control daterange"/></div>');

       }

   });


    // DataTable
    var table = $("#mytable").DataTable({

        dom: "rBftlip",

        buttons: [
        {
            extend: 'collection',
            text: 'Export',
            buttons:
                [

                    {
                        extend: "copy",
                        exportOptions: { columns: ':visible:not(:last-child)' }, //last column has the action types detail/edit/delete
                        footer:true
                    },
                    {
                        extend: "csv",
                        exportOptions: { columns: ':visible:not(:last-child)' },
                        footer: true
                    },
                    {
                        extend: "excel",
                        exportOptions: { columns: ':visible:not(:last-child)' },
                        footer:true
                    },
                    {
                        extend: "pdf",
                        exportOptions: { columns: ':visible:not(:last-child)' },
                        footer:true
                    },
                    {
                        extend: "print",
                        exportOptions: { columns: ':visible:not(:last-child)' },
                        footer: true
                    }

                ]
        }
        ],

        responsive: true,
        "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
        orderCellsTop: true,
        scrollX: true,
        colReorder: true,


        language: {
            search: '<div class="input-group"><span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>',
            searchPlaceholder: 'Search all columns',
            lengthMenu: '<div class="input-group"><span class="input-group-addon"><span class="glyphicon glyphicon-menu-hamburger"></span></span>_MENU_</div>',
            processing: "<img src='../Content/images/ajax-loader.gif'>"
        },

        processing: true,


        "initComplete": function (settings, json) {
            //  $("#mytable_processing").css("visibility", "hidden");
            $('#mytable').fadeIn();
        },



        "footerCallback": function( tfoot, data, start, end, display ) {
            var info = $('#mytable').DataTable().page.info();
            $(tfoot).find('td').eq(0).html("Total Count: " + info.recordsDisplay);


        },

    });

    new $.fn.dataTable.Buttons(table, {
        buttons: [
          {
              extend: 'colvis',
              text: 'Show/Hide Columns'

          },

        ]
    });

    //add button to top
    table.buttons(0, null).container().prependTo(
          table.table().container()
      );


    //remove class from search filter
    ($("#mytable_filter input").removeClass("input-sm"));





    //instantiate datepicker and choose your format of the dates
    $('.daterange').daterangepicker({
        ranges: {
            "Today": [moment(), moment()],
            'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
            '7 last days': [moment().subtract(6, 'days'), moment()],
            '30 last days': [moment().subtract(29, 'days'), moment()],
            'This month': [moment().startOf('month'), moment().endOf('month')],
            'Last month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
        },
        autoUpdateInput: false,
        opens:"left",
        locale: {
            cancelLabel: 'Clear',
            format: 'DD-MMM-YYYY'
        }
    });


   // $.fn.dataTableExt.afnFiltering = new Array();

   //get column index for date range
    var visiblecolumnIndex;
    var dataColumnIndex;  //current data column to work with

    $("#mytable_wrapper thead").on("mousedown", "th", function (event) {
        visiblecolumnIndex = $(this).parent().children().index($(this));
        dataColumnIndex = $("tr:first-child").children(':eq(' + visiblecolumnIndex + ')').attr('data-column-index');

    });


    var startDate;
    var endDate;



   var DateFilterFunction = (function (settings, data, iDataIndex) {

       var filterstart = startDate;
       var filterend = endDate; 
        var iStartDateCol = dataColumnIndex;
        var iEndDateCol = dataColumnIndex;

        var tabledatestart = data[iStartDateCol] !== "" ? moment(data[iStartDateCol], "DD-MMM-YYYY") : data[iStartDateCol];
        var tabledateend = data[iEndDateCol] !== "" ? moment(data[iEndDateCol], "DD-MMM-YYYY") : data[iEndDateCol];



        if (filterstart === "" && filterend === "") {
            return true;
        }

        else if ((moment(filterstart, "DD-MMM-YYYY").isSame(tabledatestart) || moment(filterstart, "DD-MMM-YYYY").isBefore(tabledatestart)) && filterend === "") {
            return true;
        }
        else if ((moment(filterstart, "DD-MMM-YYYY").isSame(tabledatestart) || moment(filterstart, "DD-MMM-YYYY").isAfter(tabledatestart)) && filterstart === "") {
            return true;
        }
        else if ((moment(filterstart, "DD-MMM-YYYY").isSame(tabledatestart) || moment(filterstart, "DD-MMM-YYYY").isBefore(tabledatestart)) && (moment(filterend, "DD-MMM-YYYY").isSame(tabledateend) || moment(filterend, "DD-MMM-YYYY").isAfter(tabledateend))) {
            return true;
        }

        return false;


    });




   $(".daterange", this).on('apply.daterangepicker', function (ev, picker) {
       ev.preventDefault();
       $(this).val(picker.startDate.format('DD-MMM-YYYY') + ' to ' + picker.endDate.format('DD-MMM-YYYY'));
       startDate = picker.startDate.format('DD-MMM-YYYY');
       endDate = picker.endDate.format('DD-MMM-YYYY');
       $.fn.dataTableExt.afnFiltering.push(DateFilterFunction);

       table.draw();

   });

   $(".daterange", this).on('cancel.daterangepicker', function (ev, picker) {
       ev.preventDefault();
       $(this).val('');
       startDate = '';
       endDate = '';
       $.fn.dataTableExt.afnFiltering.push(DateFilterFunction);

       table.draw();


   });



    //hide unnecessary columns
    var column = table.columns($('.HideColumn'));
    // Toggle the visibility
    column.visible(!column.visible());

    // Apply the search
    $.each($('.input-filter', table.table().header()), function () {
        var column = table.column($(this).index());
        //onsole.log(column);
        $('input', this).on('keyup change', function () {
            if (column.search() !== this.value) {
                column
                    .search(this.value)
                    .draw();
            }
        });
    });





}); /////////////////////// end of Datatable function

【问题讨论】:

    标签: javascript jquery datatables daterangepicker


    【解决方案1】:

    来晚了,但我得到了它与下面给出的代码完美地工作:

    这是我的代码中的一个 sn-p,我在其中过滤了年龄和日期。你只需要用你自己的数据来改变它。在初始化 DataTable 后放置此代码:

         $.fn.dataTable.ext.search.push(
            function( settings, data, dataIndex ) {
                var min = parseInt( $('#minAge').val());
                var max = parseInt( $('#maxAge').val());
                var age = parseFloat( data[3] ) || 0; // use data for the age column
    
                var dateMin = Date.parse($('#dateMin').val());
                var dateMax = Date.parse($('#dateMax').val());
                var date = parseFloat( Date.parse(data[4]) ) || 0; //use data for date column
    
                if ( (( isNaN( min ) && isNaN( max ) ) ||
                    ( isNaN( min ) && age <= max ) ||
                    ( min <= age   && isNaN( max ) ) ||
                    ( min <= age   && age <= max )) && 
                    (( isNaN(dateMin) && isNaN(dateMax)) || 
                    ( isNaN(dateMin) && date <= dateMax) || 
                    ( dateMin <= date && isNaN( dateMax )) ||
                    ( dateMin <= date && date <= dateMax)) )
                {
                    return true;
                }
                    return false;
            }
        );
    

    现在用 jquery 或任何东西在你要进行过滤的输入框中放置一个 keyup 触发器

    然后放

    table.draw();//where table is your initialized DataTable
    

    瞧,你完成了!

    【讨论】:

      【解决方案2】:

      我最终让它工作了。这是我为感兴趣的人提供的解决方案:

      https://jsfiddle.net/a9pLk0ud/2/

      //instantiate datepicker and choose your format of the dates
          $('.daterange').daterangepicker({
              ranges: {
                  "Today": [moment(), moment()],
                  'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                  '7 last days': [moment().subtract(6, 'days'), moment()],
                  '30 last days': [moment().subtract(29, 'days'), moment()],
                  'This month': [moment().startOf('month'), moment().endOf('month')],
                  'Last month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
                  'Blank date': [moment("0001-01-01"), moment("0001-01-01")]
              }
              ,
              autoUpdateInput: false,
              opens: "left",
              locale: {
                  cancelLabel: 'Clear',
                  format: 'DD-MMM-YYYY'
              }
          });
      
          var startDate;
          var endDate;
          var dataIdx;  //current data column to work with
      
      
          $("#mytable_wrapper thead").on("mousedown", "th", function (event) {
              var visIdx = $(this).parent().children().index($(this));
              dataIdx = table.column.index('fromVisible', visIdx);
          });
      
      
      
      
          // Function for converting a dd/mmm/yyyy date value into a numeric string for comparison (example 01-Dec-2010 becomes 20101201
          function parseDateValue(rawDate) {
      
              var d = moment(rawDate, "DD-MMM-YYYY").format('DD-MM-YYYY');
              var dateArray = d.split("-");
              var parsedDate = dateArray[2] + dateArray[1] + dateArray[0];
              return parsedDate;
          }
      
      
      
      
      
          //filter on daterange
          $(".daterange").on('apply.daterangepicker', function (ev, picker) {
      
              ev.preventDefault();
      
      
      
              //if blank date option was selected
              if ((picker.startDate.format('DD-MMM-YYYY') == "01-Jan-0001") && (picker.endDate.format('DD-MMM-YYYY')) == "01-Jan-0001") {
                  $(this).val('Blank');
      
      
                  val = "^$";
      
                  table.column(dataIdx)
                     .search(val, true, false, true)
                     .draw();
      
              }
              else {
                  //set field value
                  $(this).val(picker.startDate.format('DD-MMM-YYYY') + ' to ' + picker.endDate.format('DD-MMM-YYYY'));
      
      
      
                  //run date filter
                  startDate = picker.startDate.format('DD-MMM-YYYY');
                  endDate = picker.endDate.format('DD-MMM-YYYY');
      
                  var dateStart = parseDateValue(startDate);
                  var dateEnd = parseDateValue(endDate);
      
                  var filteredData = table
                          .column(dataIdx)
                          .data()
                          .filter(function (value, index) {
      
                              var evalDate = value === "" ? 0 : parseDateValue(value);
                              if ((isNaN(dateStart) && isNaN(dateEnd)) || (evalDate >= dateStart && evalDate <= dateEnd)) {
      
                                  return true;
                              }
                              return false;
                          });
      
      
                  var val = "";
                  for (var count = 0; count < filteredData.length; count++) {
      
                      val += filteredData[count] + "|";
                  }
      
                  val = val.slice(0, -1);
      
      
                  table.column(dataIdx)
                        .search(val ? "^" + val + "$" : "^" + "-" + "$", true, false, true)
                        .draw();
              }
      
      
             
      
          });
      
      
          $(".daterange").on('cancel.daterangepicker', function (ev, picker) {
              ev.preventDefault();
              $(this).val('');
              table.column(dataIdx)
                    .search("")
                    .draw();
      
           
      
      
      
          });

      【讨论】: