You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataTables实现单列过滤报CURSORPOSITION错误筛选无效

问题说明

目标为实现DataTables单列过滤功能,参考官方FixedHeader扩展的列过滤实现方案。
当前故障表现:

  • 在筛选输入框键入内容时,DataTable未执行任何过滤操作
  • 控制台抛出与CURSORPOSITION相关的错误,报错截图如下:
    报错截图
    报错截图
    已对照官方指南编写代码、查阅相关资料后仍无法实现预期单列过滤效果。
现有代码

视图层(Views)代码

<table id="example" class="table table-bordered table-hover table-striped is-narrow is-hoverable is-fullwidth text-nowrap" style="width: 100%;">
    <thead>
        <tr>
            <th>TESTING ID</th>
            <th>TESTING ACTION</th>
            <th>TESTING DESC</th>
            <th>TESTING Date</th>
            <th>TESTING VENUE</th>
            <th>TESTING TICKET</th>
        </tr>
    </thead>
    <tbody>
    </tbody>          
</table>

DataTables Ajax初始化代码

$(document).ready(function() {
    $('#example thead tr')
        .clone(true)
        .addClass('filters')
        .appendTo('#example thead');
    
    table = $('#example').DataTable({ 
        dom: 'lfrtip',
        "processing": false,
        "serverSide": true,  
        orderCellsTop: true,
        fixedHeader: true,
        
        initComplete: function () {
            var api = this.api();
            // 遍历每一列
            api
                .columns()
                .eq(0)
                .each(function (colIdx) {
                    // 给筛选行的单元格插入输入框
                    var cell = $('.filters th').eq(
                        $(api.column(colIdx).header()).index()
                    );
                    var title = $(cell).text();
                    $(cell).html('<input type="text" placeholder="' + title + '" />');

                    // 绑定输入框事件
                    $(
                        'input',
                        $('.filters th').eq($(api.column(colIdx).header()).index())
                    )
                        .off('keyup change')
                        .on('change', function (e) {
                            $(this).attr('title', $(this).val());
                            var regexr = '({search})';
                            var cursorPosition = this.selectionStart;
                            // 执行列搜索
                            api
                                .column(colIdx)
                                .search(
                                    this.value != ''
                                        ? regexr.replace('{search}', '(((' + this.value + ')))')
                                        : '',
                                    this.value != '',
                                    this.value == ''
                                )
                                .draw();
                        })
                        .on('keyup', function (e) {
                            e.stopPropagation();
                            $(this).trigger('change');
                            $(this)
                                .focus()[0]
                                .setSelectionRange(cursorPosition, cursorPosition);
                        });
                });
        },

        // Ajax数据源配置
        "ajax": {
            "url": "<?php echo site_url('controller/lists')?>",
            "type": "POST",
            async:true,
            dataType: "json", 
            "data": function(data){
                
            },
        },

        // 列配置
        "columnDefs": [
            { 
                "targets": [ 0 ],
                "orderable": false,
            },
            { 
                "targets": [ -1 ],
                "orderable": false,
            },
        ],
    });
});
故障原因与修复方法

故障根因

  1. CURSORPOSITION相关报错:变量作用域错误
    cursorPosition变量定义在change事件的回调函数内部,属于局部变量,keyup事件回调执行时无法访问到该变量,调用setSelectionRange时传入undefined直接触发报错,同时导致输入焦点异常丢失,无法正常触发draw后的渲染逻辑。

  2. 过滤不生效:请求参数被空函数覆盖
    开启serverSide: true服务端处理模式后,所有过滤、分页、排序逻辑都需要后端执行,但现有代码的ajax.data回调是空实现,既没有返回DataTables默认构造的包含列搜索条件、分页、排序信息的参数对象,也没有手动拼接搜索参数,后端根本收不到任何筛选条件,自然不会返回过滤后的结果。

  3. 额外注意:后端接口需要适配服务端模式的参数规则,解析请求中携带的各列search.value字段,对应拼接数据库查询条件,才能返回正确的过滤结果。

修复步骤

  • 修复光标位置变量的作用域问题,调整事件逻辑,避免draw后焦点跳转导致输入中断
  • 补全ajax.data回调逻辑,将DataTables生成的请求参数正常传递给后端接口
  • 适配后端接口的参数解析逻辑,处理列过滤条件

修正后的核心代码参考

  1. 修正initComplete内的输入框事件逻辑:
initComplete: function () {
    var api = this.api();
    api.columns().eq(0).each(function (colIdx) {
        var cell = $('.filters th').eq($(api.column(colIdx).header()).index());
        var title = $(cell).text();
        $(cell).html('<input type="text" placeholder="' + title + '" />');

        $('input', cell)
            .off('keyup change')
            .on('keyup change', function (e) {
                e.stopPropagation();
                var inputEl = this;
                var cursorPosition = inputEl.selectionStart;
                // 列搜索
                api.column(colIdx)
                    .search(
                        this.value ? '(((' + this.value + ')))' : '',
                        !!this.value,
                        !this.value
                    )
                    .draw(false); // 传false保留分页状态,避免跳回第一页
                // 重绘后重置光标位置
                $(inputEl).focus()[0].setSelectionRange(cursorPosition, cursorPosition);
            });
    });
},
  1. 修正ajax.data配置,传递默认参数:
"ajax": {
    "url": "<?php echo site_url('controller/lists')?>",
    "type": "POST",
    async:true,
    dataType: "json", 
    "data": function(data){
        // 如有额外自定义参数可以在这里合并到data对象中
        return data; // 必须返回参数对象,否则DataTables的请求参数会丢失
    },
},
  1. 后端接口适配:接收POST请求中columns数组下每一列的search.value值,对应组装SQL的WHERE条件,完成过滤查询后按照DataTables服务端模式要求的格式返回数据即可。

内容的提问来源于stack exchange,提问作者Ulquiorra Schiffer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:42:14