向 HTML 表格添加选择框列筛选器

在表格的某些列添加筛选器有助于数据分析,在生物数据里这个功能尤其重要。今天在项目的基因表达数据表实现了这个功能。

使用 DataTables 自带例子

DataTables 是特别实用的 jQuery 表格插件,官方文档介绍了添加列筛选器的方式(详见 https://www.datatables.net/release-datatables/examples/api/multi_filter_select.html):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$(document).ready(function() {
$('#example').DataTable( {
initComplete: function () {
this.api().columns().every( function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);

column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
} );

column.data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' )
} );
} );
}
} );
} );

其原理是在表格的 <tfoot> 标签里放置 <select> 并添加 search 功能,实际使用时给 <tfoot> 加入样式 display: table-header-group 即可满足需求。

效果图:

手写实现前置的 tfoot 标签

经过测试,ChromeFirefox 正常显示预期效果,然而 IEEDGE 浏览器始终把 <tfoot> 标签放置于 <tbody> 下面 (╯°Д°)╯︵ ┻━┻ 接着花了很长时间 google 也没找到解决方法,面对硬性的需求,只好硬着头皮尝试。

具体做法:

  1. <thead> 标签里新建一个 <tr> 标签。
  2. 构建 DataTables 后调换 <thead> 把新建的标签提前。
  3. 手动处理 DataTables 的 column visibility 设置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
generateIETfoot('table2');
var numColumns = [3, 6, 7, 8];
var statusColumns = [9, 10, 11];
$('#table2').DataTable({
"columnDefs": [{
"targets": t,
"visible": false,
"searchable": false
}],
"lengthMenu": [[20, 50, 100, -1], [20, 50, 100, "All"]],
"pageLength": 20,
"initComplete": columnFilterGeneratorFunction('table2', numColumns, statusColumns)
});

function generateIETfoot(tableName) {
var IETfoot = $('<tr></tr>').prependTo($('#' + tableName + ' thead'));
$('#' + tableName + ' thead tr:eq(1) th').each(function () {
IETfoot.append($('<th><select style="width: 85%; min-width: 90px"><option value="">-- filter --</option></select></th>'));
});
return IETfoot;
}

function columnFilterGeneratorFunction(tableName, numColumns, statusColumns) {
return function () {
var IETfoot = $('#' + tableName + ' thead tr:eq(0)');
IETfoot.appendTo($('#' + tableName + ' thead'));
var IEThCnt = 0;
this.api().columns().every(function (i) {
var column = this;
if (column.visible()) {
var select = IETfoot.find('th:eq(' + IEThCnt++ + ') > select')
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);

column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
if (numColumns.indexOf(i) != -1)
column.data().unique().sort(numComparer).each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
else if (statusColumns.indexOf(i) != -1)
column.data().unique().sort(statusComparer).each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
else
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
}
});
}
}
0%