在Datatables中自定义筛选时出错

时间:2017-08-13 15:42:39

标签: javascript jquery datatables

我正在尝试使用表格页脚中的文本框过滤表格。当我在这些页脚中键入一个值时,我希望调用表的过滤。为了能够键入比较运算符,我将比较函数推入了一组数据表过滤器,这些过滤器将在相应的页脚文本框中读取文本(可以有一个比较运算符,如>< =)并比较中的值该列根据比较运算符。

过滤效果完美如预期唯一的问题是我不断收到此错误:

  

未捕获DOMException:无法在'Node'上执行'appendChild':The   要删除的节点不再是此节点的子节点。也许是这样   移动到'模糊'事件处理程序?

错误之后,表格开始表现得很奇怪:焦点远离页脚中的文本框,页脚有时会移动到页眉下方的位置。

如何使表稳定并消除此错误?

请注意$.fn.dataTableExt.afnFiltering.push(内的功能:

<!DOCTYPE HTML>
<html lang="en">
<head>
    <title>
    </title>

    <link rel="stylesheet" type="text/css"
          href="https://cdn.datatables.net/v/dt/jq-2.2.4/dt-1.10.13/b-1.2.4/b-html5-1.2.4/fh-3.1.2/datatables.min.css"/>
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css"/>

    <script type="text/javascript"
            src="https://cdn.datatables.net/v/dt/jq-2.2.4/dt-1.10.13/b-1.2.4/b-html5-1.2.4/fh-3.1.2/datatables.min.js"></script>
    <script src="http://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.13/sorting/natural.js"></script>
    <script src="http://www.chartjs.org/dist/2.6.0/Chart.bundle.js"></script>
    <script src="http://www.chartjs.org/samples/latest/utils.js"></script>



</head>
<body>

<img id="loader"
     style="
        width:36px;
        height:36px;
        display: none;
        position:absolute;
        top:50%;
        left:50%;
        margin-top:-18px;
        margin-left:-18px;"/>
<p><a href="/accounts/logout/">Logout</a> | <a href="/accounts/profile/">Home</a></p>

<div id="title">
    <b style="font-size:200%">Optimize proxies<br></b>
</div>
<div id="proxy_history_dialog" title="Proxy history" style="display:none;" font="8">
</div>
<div id="graph_dialog" title="Extraction - daily vs accumulative" style="display:none;" font="8">


</div>
<table id='p_table-id' class="display" cellspacing="0" style="float: left;">
    <thead>
    <tr>

        <th>Site id</th>

        <th>Site name</th>

        <th>Is optimized</th>

        <th>Proxy group</th>

        <th>Price level</th>

        <th>Duration</th>

        <th>Avg extraction score (cached)</th>

        <th>Max extraction in last 3 days (cached)</th>

        <th>Overlap score</th>

        <th>Last status</th>

        <th>Actions</th>
        <th>Change proxy</th>

    </tr>
    </thead>
    <tfoot>
    <tr>

        <th>Site id</th>

        <th>Site name</th>

        <th>Is optimized</th>

        <th>Proxy group</th>

        <th>Price level</th>

        <th>Duration</th>

        <th>Avg extraction score (cached)</th>

        <th>Max extraction in last 3 days (cached)</th>

        <th>Overlap score</th>

        <th>Last status</th>

        <th>Actions</th>
        <th>Change proxy</th>
    </tr>
    </tfoot>
    <tbody>

    <tr>

        <td>-106</td>

        <td>target.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>14 days 11:17:57</td>

        <td>83.18</td>

        <td>91.03</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_-106">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>-105</td>

        <td>walmart.com (P)</td>

        <td>True</td>

        <td>us</td>

        <td>2</td>

        <td>27 days 23:58:15</td>

        <td>96.21</td>

        <td>97.28</td>

        <td>None</td>

        <td>failed_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_-105">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>-104</td>

        <td>bestonix (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>14 days 11:17:56</td>

        <td>64.05</td>

        <td>63.91</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_-104">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>209</td>

        <td>rockbottomgolf.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>31 days 00:56:48</td>

        <td>95.73</td>

        <td>95.02</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_209">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>210</td>

        <td>golfgalaxy.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>14 days 11:17:54</td>

        <td>87.91</td>

        <td>90.53</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_210">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>211</td>

        <td>tgw.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>14 days 11:17:53</td>

        <td>60.06</td>

        <td>64.00</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_211">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>244</td>

        <td>amazon_golf (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>53 days 18:23:36</td>

        <td>92.38</td>

        <td>93.20</td>

        <td>None</td>

        <td>None</td>


       <td></td>

        <td>
            Change proxy:
            <select id="proxy_dp_244">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>246</td>

        <td>golfdiscount.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>31 days 00:56:46</td>

        <td>85.85</td>

        <td>75.90</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_246">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>248</td>

        <td>globalgolf.com (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>31 days 00:56:45</td>

        <td>61.02</td>

        <td>65.17</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_248">

            </select></option>



        </td>
    </tr>

    <tr>

        <td>658</td>

        <td>sephora_ulta_new (P)</td>

        <td>True</td>

        <td>shader_us</td>

        <td>1</td>

        <td>13 days 11:17:48</td>

        <td>98.55</td>

        <td>99.16</td>

        <td>None</td>

        <td>successful_downgrade</td>


        <td style="position: relative;">



        <td>
            Change proxy:
            <select id="proxy_dp_658">

            </select></option>



        </td>
    </tr>

    </tbody>
</table>

<script>
    function natural_compare(a, b, html) {
        var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?%?$|^0x[0-9a-f]+$|[0-9]+)/gi,
            sre = /(^[ ]*|[ ]*$)/g,
            dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
            hre = /^0x[0-9a-f]+$/i,
            ore = /^0/,
            htmre = /(<([^>]+)>)/ig,
            // convert all to strings and trim()
            x = a.toString().replace(sre, '') || '',
            y = b.toString().replace(sre, '') || '';
        // remove html from strings if desired
        if (!html) {
            x = x.replace(htmre, '');
            y = y.replace(htmre, '');
        }
        // chunk/tokenize
        var xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
            yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
            // numeric, hex or date detection
            xD = parseInt(x.match(hre), 10) || (xN.length !== 1 && x.match(dre) && Date.parse(x)),
            yD = parseInt(y.match(hre), 10) || xD && y.match(dre) && Date.parse(y) || null;

        // first try and sort Hex codes or Dates
        if (yD) {
            if (xD < yD) {
                return -1;
            }
            else if (xD > yD) {
                return 1;
            }
        }

        // natural sorting through split numeric strings and default strings
        for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
            // find floats not starting with '0', string or 0 if not defined (Clint Priest)
            var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc], 10) || xN[cLoc] || 0;
            var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc], 10) || yN[cLoc] || 0;
            // handle numeric vs string comparison - number < string - (Kyle Adams)
            if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
                return (isNaN(oFxNcL)) ? 1 : -1;
            }
            // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
            else if (typeof oFxNcL !== typeof oFyNcL) {
                oFxNcL += '';
                oFyNcL += '';
            }
            if (oFxNcL < oFyNcL) {
                return -1;
            }
            if (oFxNcL > oFyNcL) {
                return 1;
            }
        }
        return 0;
    }


    $(document).ready(function () {
        ///////////////////////////////////////////////////////////////////////////
        DURATION_COL_IX = 5;
        // Setup column search - add a text input to each footer cell
        $('#p_table-id').find('tfoot th').each(function () {
            var title = $(this).text();
            $(this).html('<input type="text" placeholder="Filter">');
        });
        // DataTable
        var table = $('#p_table-id').DataTable({
            "orderClasses": false,
            lengthChange: false,
            columnDefs: [
                {type: 'natural', targets: '_all'}
            ],
            "dom": '<"top" li>lt<"bottom"i><"clear">',

            fixedHeader: {
                footer: true
            },
            'iDisplayLength': -1,
            "order": [[5, "asc"]]
        });
        // Apply the search todo: delete
        var last_changed_footer_col;
        table.columns().every(function () {
            var col = this;
            $('input', this.footer()).on('keyup change', function () {
                last_changed_footer_col = col.footer().cellIndex;
                table.draw();


            });
        });
        $.fn.dataTableExt.afnFiltering.push(
            function (oSettings, aData, iDataIndex) {


                var column = table.column(last_changed_footer_col);

                var footer_txt = $('input', column.footer()).val().replace(/\s*/g, '');

                var cell_data = aData[last_changed_footer_col];
                if (footer_txt.match(/^[<>=].+/)) {

                    var comparator = footer_txt.match(/^([<>=]).*$/)[1];
                    var val_regex = new RegExp('^' + comparator + '(.*)');
                    var val = footer_txt.match(val_regex)[1];
                    switch (comparator) {
                        case '<':
                            return natural_compare(cell_data, val, false) < 0;
                        case '>':
                            return natural_compare(cell_data, val, false) > 0;
                        case '=':
                            return natural_compare(cell_data, val, false) === 0;
                    }
                } else {
                    //just filter
                    return cell_data.search(footer_txt) >= 0;


                }
            }
        );
        ///////////////////////////////////////////////////////////////////////////////







    });

</script>


</body>
</html>

1 个答案:

答案 0 :(得分:1)

您的问题在这一行:

$('input', this.footer()).on('keyup change', function () {

通过这种方式,您可以调用两次搜索方法,从而获得错误。

因此,您需要将其更改为:

$('input', this.footer()).on('input', function () {

function natural_compare(a, b, html) {
    var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?%?$|^0x[0-9a-f]+$|[0-9]+)/gi,
            sre = /(^[ ]*|[ ]*$)/g,
            dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
            hre = /^0x[0-9a-f]+$/i,
            ore = /^0/,
            htmre = /(<([^>]+)>)/ig,
    // convert all to strings and trim()
            x = a.toString().replace(sre, '') || '',
            y = b.toString().replace(sre, '') || '';
    // remove html from strings if desired
    if (!html) {
        x = x.replace(htmre, '');
        y = y.replace(htmre, '');
    }
    // chunk/tokenize
    var xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
            yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'),
    // numeric, hex or date detection
            xD = parseInt(x.match(hre), 10) || (xN.length !== 1 && x.match(dre) && Date.parse(x)),
            yD = parseInt(y.match(hre), 10) || xD && y.match(dre) && Date.parse(y) || null;

    // first try and sort Hex codes or Dates
    if (yD) {
        if (xD < yD) {
            return -1;
        }
        else if (xD > yD) {
            return 1;
        }
    }

    // natural sorting through split numeric strings and default strings
    for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
        // find floats not starting with '0', string or 0 if not defined (Clint Priest)
        var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc], 10) || xN[cLoc] || 0;
        var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc], 10) || yN[cLoc] || 0;
        // handle numeric vs string comparison - number < string - (Kyle Adams)
        if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
            return (isNaN(oFxNcL)) ? 1 : -1;
        }
        // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
        else if (typeof oFxNcL !== typeof oFyNcL) {
            oFxNcL += '';
            oFyNcL += '';
        }
        if (oFxNcL < oFyNcL) {
            return -1;
        }
        if (oFxNcL > oFyNcL) {
            return 1;
        }
    }
    return 0;
}


$(document).ready(function () {
    ///////////////////////////////////////////////////////////////////////////
    DURATION_COL_IX = 5;
    // Setup column search - add a text input to each footer cell
    $('#p_table-id').find('tfoot th').each(function () {
        var title = $(this).text();
        $(this).html('<input type="text" placeholder="Filter">');
    });
    // DataTable
    var table = $('#p_table-id').DataTable({
        "orderClasses": false,
        lengthChange: false,
        columnDefs: [
            {type: 'natural', targets: '_all'}
        ],
        "dom": '<"top" li>lt<"bottom"i><"clear">',
        fixedHeader: {
            footer: true
        },
        'iDisplayLength': -1,
        "order": [[5, "asc"]]
    });
    // Apply the search todo: delete
    var last_changed_footer_col;
    table.columns().every(function () {
        var col = this;
        $('input', this.footer()).on('input', function (e) {
            //substitute input with keyup change events
            // and print to the console.....
            //console.log(e.type);
            last_changed_footer_col = col.footer().cellIndex;
            table.draw(false);
        });
    });
    $.fn.dataTableExt.afnFiltering.push(
            function (oSettings, aData, iDataIndex) {
                var column = table.column(last_changed_footer_col);
                var footer_txt = $('input', column.footer()).val().replace(/\s*/g, '');
                var cell_data = aData[last_changed_footer_col];
                if (footer_txt.match(/^[<>=].+/)) {
                    var comparator = footer_txt.match(/^([<>=]).*$/)[1];
                    var val_regex = new RegExp('^' + comparator + '(.*)');
                    var val = footer_txt.match(val_regex)[1];
                    switch (comparator) {
                        case '<':
                            return natural_compare(cell_data, val, false) < 0;
                        case '>':
                            return natural_compare(cell_data, val, false) > 0;
                        case '=':
                            return natural_compare(cell_data, val, false) === 0;
                    }
                } else {
                    //just filter
                    return cell_data.search(footer_txt) >= 0;
                }
            }
    );
});
<link rel="stylesheet" type="text/css"
href="https://cdn.datatables.net/v/dt/jq-2.2.4/dt-1.10.13/b-1.2.4/b-html5-1.2.4/fh-3.1.2/datatables.min.css"/>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css"/>

<script type="text/javascript"
src="https://cdn.datatables.net/v/dt/jq-2.2.4/dt-1.10.13/b-1.2.4/b-html5-1.2.4/fh-3.1.2/datatables.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.13/sorting/natural.js"></script>


<img id="loader"
     style="
        width:36px;
        height:36px;
        display: none;
        position:absolute;
        top:50%;
        left:50%;
        margin-top:-18px;
        margin-left:-18px;"/>

<p><a href="/accounts/logout/">Logout</a> | <a href="/accounts/profile/">Home</a></p>

<div id="title">
    <b style="font-size:200%">Optimize proxies<br></b>
</div>
<div id="proxy_history_dialog" title="Proxy history" style="display:none;" font="8">
</div>
<div id="graph_dialog" title="Extraction - daily vs accumulative" style="display:none;" font="8">


</div>
<table id='p_table-id' class="display" cellspacing="0" style="float: left;">
    <thead>
    <tr>
        <th>Site id</th>
        <th>Site name</th>
        <th>Is optimized</th>
        <th>Proxy group</th>
        <th>Price level</th>
        <th>Duration</th>
        <th>Avg extraction score (cached)</th>
        <th>Max extraction in last 3 days (cached)</th>
        <th>Overlap score</th>
        <th>Last status</th>
        <th>Actions</th>
        <th>Change proxy</th>
    </tr>
    </thead>
    <tfoot>
    <tr>
        <th>Site id</th>
        <th>Site name</th>
        <th>Is optimized</th>
        <th>Proxy group</th>
        <th>Price level</th>
        <th>Duration</th>
        <th>Avg extraction score (cached)</th>
        <th>Max extraction in last 3 days (cached)</th>
        <th>Overlap score</th>
        <th>Last status</th>
        <th>Actions</th>
        <th>Change proxy</th>
    </tr>
    </tfoot>
    <tbody>
    <tr>
        <td>-106</td>
        <td>target.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>14 days 11:17:57</td>
        <td>83.18</td>
        <td>91.03</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_-106">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>-105</td>
        <td>walmart.com (P)</td>
        <td>True</td>
        <td>us</td>
        <td>2</td>
        <td>27 days 23:58:15</td>
        <td>96.21</td>
        <td>97.28</td>
        <td>None</td>
        <td>failed_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_-105">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>-104</td>
        <td>bestonix (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>14 days 11:17:56</td>
        <td>64.05</td>
        <td>63.91</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_-104">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>209</td>
        <td>rockbottomgolf.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>31 days 00:56:48</td>
        <td>95.73</td>
        <td>95.02</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_209">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>210</td>
        <td>golfgalaxy.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>14 days 11:17:54</td>
        <td>87.91</td>
        <td>90.53</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_210">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>211</td>
        <td>tgw.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>14 days 11:17:53</td>
        <td>60.06</td>
        <td>64.00</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_211">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>244</td>
        <td>amazon_golf (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>53 days 18:23:36</td>
        <td>92.38</td>
        <td>93.20</td>
        <td>None</td>
        <td>None</td>
        <td></td>
        <td>
            Change proxy:
            <select id="proxy_dp_244">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>246</td>
        <td>golfdiscount.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>31 days 00:56:46</td>
        <td>85.85</td>
        <td>75.90</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_246">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>248</td>
        <td>globalgolf.com (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>31 days 00:56:45</td>
        <td>61.02</td>
        <td>65.17</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_248">
            </select></option>
        </td>
    </tr>
    <tr>
        <td>658</td>
        <td>sephora_ulta_new (P)</td>
        <td>True</td>
        <td>shader_us</td>
        <td>1</td>
        <td>13 days 11:17:48</td>
        <td>98.55</td>
        <td>99.16</td>
        <td>None</td>
        <td>successful_downgrade</td>
        <td style="position: relative;">
        <td>
            Change proxy:
            <select id="proxy_dp_658">
            </select></option>
        </td>
    </tr>
    </tbody>
</table>

相关问题