DataTables columnFilter 数字范围过滤

Posted

技术标签:

【中文标题】DataTables columnFilter 数字范围过滤【英文标题】:DataTables columnFilter number-range filtering 【发布时间】:2015-09-13 10:41:04 【问题描述】:

我有数据库,其中"BIRTH_DATE" 列中有日期(例如2015-06-26)。我使用DataTables 为用户显示信息。我想做数字范围搜索。但是当我使用DataTables 插件ColumnFilter 并尝试使用number-range 类型过滤器时它不起作用。

只要我在fromto 字段中输入任何值,它就会告诉我没有结果。但是,如果在同一列中有一行日期是这样写的,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 中运行良好。

【问题讨论】:

【参考方案1】:

我也遇到过这个问题:

可能有两个原因:

1) iMin,iMax,iValue 的值必须在 秒表示number of milliseconds since 1970/01/01 检查 这个getTime()

例如

var iMin = document.getElementById(sFromId).value

因为比较 (iMin == "" &amp;&amp; iValue &lt; iMax) 您使用算术运算符 (=,&lt;,&gt;) 所以这三个变量的值必须是数字。

2) 请先确认:我猜您的日期格式是这样的2015-06-26 您必须将日期转换为这种格式2015/06/26 才能正常工作。不知道为什么,但在某些情况下 jquery 不接受 1970-01-011970/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() 函数来获取number of milliseconds since 1970/01/01

所以我猜(因为我不知道你的 HTML)这会对你有所帮助。

【讨论】:

【参考方案2】:

你的专栏BIRTH_DATE是什么类型的?

我的建议是把它设为datetime(看起来像2015-06-26 16:10:18.820,虽然它也可能没有精确的时间)。 如果您将列类型设置为date,则数据表可以按datatime 排序。

有关 DataTables https://datatables.net/reference/option/columns.type 中 column.type 的更详细说明,请参见此处

【讨论】:

我的专栏BIRTH_DATEvarchar 类型。而且我无法更改它,因为我每天都会收到大量新数据,并且在我收到的BIRTH_DATE 列中的数据是varchar。如果我改变它,每次我想上传新数据时都必须这样做。 Date 列将接受插入中的字符串日期,因此您收到的内容是否列为 varchar 并不重要,只需输入它,mysql 就会将其插入 DATE 列。 dev.mysql.com/doc/refman/5.1/en/datetime.html 并且不要听任何人告诉你将日期存储在 DATE 或 DATETIME 列之外的任何内容中,一旦你这样做了,你就不能使用内置的日期函数并最终遇到这样的问题.此外,数据表并不关心数据在数据库中存储的内容,它是 html 中的所有字符串。只有格式正确才能使日期范围过滤器正常工作。【参考方案3】:

试试date-range,而不是number-range。 See example here

【讨论】:

已经试过了。首先,日期范围对我来说根本不起作用。第二 - 我需要输入文本字段而不是日期选择器【参考方案4】:

首先,在您的数据库中对您的表运行更新以删除birth_date 列中的“-”(如果需要)。

其次,在插入之前在数据库中创建一个触发器,将BIRTH_DATE varchar 格式化为所需的格式。

然后您将能够在datatable 中使用初始number_range 搜索进行过滤。

但是,正如 Mazet 所说,最好使用 datetime 以获得最佳查询性能。如果这是不可能的,那么你有我上面的快速解决方法。

【讨论】:

以上是关于DataTables columnFilter 数字范围过滤的主要内容,如果未能解决你的问题,请参考以下文章

[使用多个选择下拉列表过滤HTML表

将 DataTables 插件与 django 框架集成

如何在c#中动态组合两个或多个DataTables

当前页面的 JQuery DataTables 列复选框

在搜索中内置的DataTables - 禁用“onKeyUp”触发器

如何使用jQuery将子元素从一个父元素移动到另一个父元素[重复]