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, }, ], }); });
故障原因与修复方法
故障根因
CURSORPOSITION相关报错:变量作用域错误cursorPosition变量定义在change事件的回调函数内部,属于局部变量,keyup事件回调执行时无法访问到该变量,调用setSelectionRange时传入undefined直接触发报错,同时导致输入焦点异常丢失,无法正常触发draw后的渲染逻辑。过滤不生效:请求参数被空函数覆盖
开启serverSide: true服务端处理模式后,所有过滤、分页、排序逻辑都需要后端执行,但现有代码的ajax.data回调是空实现,既没有返回DataTables默认构造的包含列搜索条件、分页、排序信息的参数对象,也没有手动拼接搜索参数,后端根本收不到任何筛选条件,自然不会返回过滤后的结果。额外注意:后端接口需要适配服务端模式的参数规则,解析请求中携带的各列
search.value字段,对应拼接数据库查询条件,才能返回正确的过滤结果。
修复步骤
- 修复光标位置变量的作用域问题,调整事件逻辑,避免draw后焦点跳转导致输入中断
- 补全
ajax.data回调逻辑,将DataTables生成的请求参数正常传递给后端接口 - 适配后端接口的参数解析逻辑,处理列过滤条件
修正后的核心代码参考
- 修正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); }); }); },
- 修正ajax.data配置,传递默认参数:
"ajax": { "url": "<?php echo site_url('controller/lists')?>", "type": "POST", async:true, dataType: "json", "data": function(data){ // 如有额外自定义参数可以在这里合并到data对象中 return data; // 必须返回参数对象,否则DataTables的请求参数会丢失 }, },
- 后端接口适配:接收POST请求中
columns数组下每一列的search.value值,对应组装SQL的WHERE条件,完成过滤查询后按照DataTables服务端模式要求的格式返回数据即可。
内容的提问来源于stack exchange,提问作者Ulquiorra Schiffer
相关产品推荐
相关产品推荐

