DataTables列过滤器数字范围筛选

5
我有一个数据库,其中列“BIRTH_DATE”中有日期(例如2015-06-26)。我使用DataTables来为用户显示信息。我想要进行数字范围搜索。但是当我使用DataTables插件ColumnFilter并尝试使用number-range类型过滤器时,它不起作用。
只要我在from或to字段中输入任何值,它就告诉我没有结果。但是,如果在同一列中有一个日期写成20150626的行,则会显示筛选器。因此,我理解问题在于我的数字中间的符号“-”。如何使筛选器忽略“-”符号?
数字范围过滤器代码:
function fnCreateCharRangeInput() {

        th.html(_fnRangeLabelPart(0));
        var sFromId = sTableId + 'range_from_' + i;
        var from = $('<input type="text" class="number_range_filter" id="' + sFromId + '" rel="' + i + '"/>');
        th.append(from);
        th.append(_fnRangeLabelPart(1));
        var sToId = sTableId + 'range_to_' + i;
        var to = $('<input type="text" class="number_range_filter" id="' + sToId + '" rel="' + i + '"/>');
        th.append(to);
        th.append(_fnRangeLabelPart(2));
        th.wrapInner('<span class="filterColumn filter_number_range" />');
        var index = i;
        aiCustomSearch_Indexes.push(i);



        //------------start range filtering function


        /*  Custom filtering function which will filter data in column four between two values
        *   Author:     Allan Jardine, Modified by Jovan Popovic
        */
        $.fn.dataTableExt.afnFiltering.push(
            function (oSettings, aData, iDataIndex) {
                var iMin = document.getElementById(sFromId).value * 1;
                var iMax = document.getElementById(sToId).value * 1;
                var iValue = aData[index] == "-" ? 0 : aData[index] * 1;
                if (iMin == "" && iMax == "") {
                    return true;
                }
                else if (iMin == "" && iValue < iMax) {
                    return true;
                }
                else if (iMin < iValue && "" == iMax) {
                    return true;
                }
                else if (iMin < iValue && iValue < iMax) {
                    return true;
                }
                return false;
            }
        );
        //------------end range filtering function



        $('#' + sFromId + ',#' + sToId, th).keyup(function () {

            var iMin = document.getElementById(sFromId).value * 1;
            var iMax = document.getElementById(sToId).value * 1;
            if (iMin != 0 && iMax != 0 && iMin > iMax)
                return;

            oTable.fnDraw();

        });


    }

编辑:2015-06-29

或许有人可以帮我制作这个过滤器,忽略输入格式只运行简单的操作,例如:

Select * from table where BIRTH_DATE between '2010' and '2011-12'

在SQL中,这样的查询是可以正常工作的。

4个回答

3

我也遇到了同样的问题:

可能有两个原因:

1) iMiniMaxiValue 的值必须以秒为单位,即自1970/01/01起的毫秒数,请参考getTime()

例如:

var iMin = document.getElementById(sFromId).value

因为在比较 (iMin == "" && iValue < iMax) 时使用了算术运算符 (=,<,>),所以这三个变量的值必须是数字。

2) 请先确认一下:我猜你的日期格式是这样的 2015-06-26,你需要将日期转换为这种格式 2015/06/26 才能使其正常工作。不确定为什么,但在某些情况下,jQuery 不接受 1970-01-01,而 1970/01/01 却可以完美地工作。

看一下我的函数

$.fn.dataTableExt.afnFiltering.push(
      function(oSettings, aData, iDataIndex) {
        if(chart.XminDate != '' && chart.XmaxDate !=  ''){
            minDateFilter = new Date( chart.XminDate.replace(/\-/g,'/') ).getTime();
            maxDateFilter = new Date( chart.XmaxDate.replace(/\-/g,'/') ).getTime();
            aData._date = new Date( aData[3].replace(/\-/g,'/') ).getTime();
            if (minDateFilter) {
                if (aData._date < minDateFilter) {
                    return false;
                }
            }
            if (maxDateFilter) {
                if (aData._date > maxDateFilter) {
                    return false;
                }
            }
            return true;
        }
        return true;
      }
    );

在我的函数中
 var iMin = document.getElementById(sFromId).value * 1; /*same as chart.XminDate */
 var iMax = document.getElementById(sToId).value * 1; /*same as chart.XmaxDate */
 var iValue = aData[index] == "-" ? 0 : aData[index] * 1; /*same as aData._date */

在这行中
 minDateFilter = new Date( chart.XminDate.replace(/\-/g,'/') ).getTime();

我已经将 - 替换为 /,然后创建了一个日期对象,并使用 getTime() 函数获取自 1970 年 01 月 01 日以来的毫秒数。因此,我猜(因为我不知道你的 HTML)这会对你有所帮助。

1

你的列BIRTH_DATE是什么类型?

我的建议是将其设置为datetime类型(类似于2015-06-26 16:10:18.820,尽管它也可以没有精确的小时)。
如果您将列类型设置为date,Datatables可以按datatime进行排序。

在此处查看有关DataTables中column.type的更详细描述 https://datatables.net/reference/option/columns.type


我的BIRTH_DATE列是varchar类型。我无法更改它,因为我每天都会收到大量的新数据,并且我接收到的数据中BIRTH_DATE列是varchar类型。如果我更改它,那么每当我想上传新数据时,都必须这样做。 - hockeyman
日期列将接受字符串日期插入,因此不管您收到的是varchar,只需输入它,MySQL就会将其插入到DATE列中。https://dev.mysql.com/doc/refman/5.1/en/datetime.html - David Soussan
1
不要听任何人告诉你将日期存储在除DATE或DATETIME列之外的任何地方,一旦这样做,您就无法使用内置的日期函数,并且最终会遇到像这样的问题。此外,datatables不关心数据库中存储的数据是什么,它在html中都是字符串。唯一重要的是日期范围过滤器的格式正确。 - David Soussan

0

已经尝试过了。首先,日期范围对我根本不起作用。其次,我需要输入为文本字段而不是日期选择器。 - hockeyman

0
首先,在需要的情况下,运行数据库中的更新操作,删除birth_date列中的“-”符号。
其次,在插入之前在数据库中创建一个触发器,将BIRTH_DATE varchar格式化为所需的格式。
然后,您就可以使用初始的number_range搜索在datatable中进行过滤。
但是,正如Mazet所说,最好使用datetime以获得最佳的查询性能。如果不可能,那么您可以使用上述快速解决方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接