深度链接到 DataTables
论坛中经常出现的一个问题是:"如何对一个 DataTable 进行深度链接?"通常在搜索引擎优化 (SEO) 语境下,您需要确保表格中的所有数据均可被索引,但它也可用于您希望显示带有特定预设搜索词的表格的应用中。
通常此类问题的答案是使用 初始化参数 来设置所需的选项,通过 search string,但这通常是个很常见的事情,所以泛化它是有道理的。为了达到这个目标,以下我提供一个简短的脚本,可用它从搜索字符串中提取参数,并使用它们填充一个 DataTable。
让我们先在实际应用中看看——点击以下链接,观察演示表格的行为
姓名 | 职位 | 办公室 | 年龄 | 开始日期 | 工资 |
---|---|---|---|---|---|
Tiger Nixon | System Architect | Edinburgh | 61 | 2011-04-25 | $320,800 |
Garrett Winters | Accountant | Tokyo | 63 | 2011-07-25 | $170,750 |
Ashton Cox | Junior Technical Author | San Francisco | 66 | 2009-01-12 | $86,000 |
Cedric Kelly | Senior Javascript Developer | Edinburgh | 22 | 2012-03-29 | $433,060 |
Airi Satou | Accountant | Tokyo | 33 | 2008-11-28 | $162,700 |
Brielle Williamson | Integration Specialist | New York | 61 | 2012-12-02 | $372,000 |
Herrod Chandler | Sales Assistant | San Francisco | 59 | 2012-08-06 | $137,500 |
Rhona Davidson | Integration Specialist | Tokyo | 55 | 2010-10-14 | $327,900 |
Colleen Hurst | Javascript Developer | San Francisco | 39 | 2009-09-15 | $205,500 |
Sonya Frost | Software Engineer | Edinburgh | 23 | 2008-12-13 | $103,600 |
Jena Gaines | Office Manager | London | 30 | 2008-12-19 | $90,560 |
Quinn Flynn | Support Lead | Edinburgh | 22 | 2013-03-03 | $342,000 |
Charde Marshall | Regional Director | San Francisco | 36 | 2008-10-16 | $470,600 |
Haley Kennedy | Senior Marketing Designer | London | 43 | 2012-12-18 | $313,500 |
Tatyana Fitzpatrick | Regional Director | London | 19 | 2010-03-17 | $385,750 |
Michael Silva | Marketing Designer | London | 66 | 2012-11-27 | $198,500 |
Paul Byrd | Chief Financial Officer (CFO) | New York | 64 | 2010-06-09 | $725,000 |
Gloria Little | Systems Administrator | New York | 59 | 2009-04-10 | $237,500 |
Bradley Greer | Software Engineer | London | 41 | 2012-10-13 | $132,000 |
Dai Rios | Personnel Lead | Edinburgh | 35 | 2012-09-26 | $217,500 |
Jenette Caldwell | Development Lead | New York | 30 | 2011-09-03 | $345,000 |
Yuri Berry | Chief Marketing Officer (CMO) | New York | 40 | 2009-06-25 | $675,000 |
Caesar Vance | Pre-Sales Support | New York | 21 | 2011-12-12 | $106,450 |
Doris Wilder | Sales Assistant | Sydney | 23 | 2010-09-20 | $85,600 |
Angelica Ramos | Chief Executive Officer (CEO) | London | 47 | 2009-10-09 | $1,200,000 |
Gavin Joyce | Developer | Edinburgh | 42 | 2010-12-22 | $92,575 |
Jennifer Chang | Regional Director | Singapore | 28 | 2010-11-14 | $357,650 |
Brenden Wagner | Software Engineer | San Francisco | 28 | 2011-06-07 | $206,850 |
Fiona Green | Chief Operating Officer (COO) | San Francisco | 48 | 2010-03-11 | $850,000 |
Shou Itou | Regional Marketing | Tokyo | 20 | 2011-08-14 | $163,000 |
Michelle House | Integration Specialist | Sydney | 37 | 2011-06-02 | $95,400 |
Suki Burks | Developer | London | 53 | 2009-10-22 | $114,500 |
Prescott Bartlett | Technical Author | London | 27 | 2011-05-07 | $145,000 |
Gavin Cortez | Team Leader | San Francisco | 22 | 2008-10-26 | $235,500 |
Martena Mccray | Post-Sales support | Edinburgh | 46 | 2011-03-09 | $324,050 |
Unity Butler | Marketing Designer | San Francisco | 47 | 2009-12-09 | $85,675 |
Howard Hatfield | Office Manager | San Francisco | 51 | 2008-12-16 | $164,500 |
Hope Fuentes | Secretary | San Francisco | 41 | 2010-02-12 | $109,850 |
Vivian Harrell | Financial Controller | San Francisco | 62 | 2009-02-14 | $452,500 |
Timothy Mooney | Office Manager | London | 37 | 2008-12-11 | $136,200 |
Jackson Bradshaw | Director | New York | 65 | 2008-09-26 | $645,750 |
Olivia Liang | Support Engineer | Singapore | 64 | 2011-02-03 | $234,500 |
Bruno Nash | Software Engineer | London | 38 | 2011-05-03 | $163,500 |
Sakura Yamamoto | Support Engineer | Tokyo | 37 | 2009-08-19 | $139,575 |
Thor Walton | Developer | New York | 61 | 2013-08-11 | $98,540 |
Finn Camacho | Support Engineer | San Francisco | 47 | 2009-07-07 | $87,500 |
Serge Baldwin | Data Coordinator | Singapore | 64 | 2012-04-09 | $138,575 |
Zenaida Frank | Software Engineer | New York | 63 | 2010-01-04 | $125,250 |
Zorita Serrano | Software Engineer | San Francisco | 56 | 2012-06-01 | $115,000 |
Jennifer Acosta | 初级 Javascript 开发人员 | Edinburgh | 43 | 2013-02-01 | $75,650 |
Cara Stevens | Sales Assistant | New York | 46 | 2011-12-06 | $145,600 |
Hermione Butler | Regional Director | London | 47 | 2011-03-21 | $356,250 |
Lael Greer | Systems Administrator | London | 21 | 2009-02-27 | $103,500 |
Jonas Alexander | Developer | San Francisco | 30 | 2010-07-14 | $86,500 |
Shad Decker | Regional Director | Edinburgh | 51 | 2008-11-13 | $183,000 |
Michael Bruce | Javascript Developer | Singapore | 29 | 2011-06-27 | $183,000 |
Donna Snider | 客户支持 | New York | 27 | 2011-01-25 | $112,000 |
姓名 | 职位 | 办公室 | 年龄 | 开始日期 | 工资 |
此示例的代码很简单
$('#myTable').DataTable( $.fn.dataTable.ext.deepLink( [
'search.search', 'order', 'displayStart'
] ) );
还需要在您的页面中包含深度链接脚本
用法
在您自己的页面中使用此脚本的关键元素是 $.fn.dataTable.ext.deepLink
函数。它带有一个参数:允许搜索参数指定的选项的数组,并返回一个包含这些初始化选项的对象,可以像上面一样直接传递给 DataTable。
采用白名单方法来限制出于安全考虑可以使用哪些选项。例如,您不太可能希望允许用户修改 ajax
、serverSide
或 scrollY
参数。如果给出的参数未在白名单中,将忽略该参数。话虽如此,如果您在一个希望使用任何和所有参数的环境中使用应用程序,则可以将 all
指定为该函数的唯一参数,这将允许所有参数。
一个简单的示例:允许从搜索字符串设置 search.search
参数
$('#myTable').DataTable( $.fn.dataTable.ext.deepLink( [
'search.search'
] );
扩展默认值
由于 deepLink()
函数只返回一个对象,因此您可以提供可选地可以被搜索字符串覆盖的默认值,或者反之使用可选参数来覆盖来自搜索字符串的任何参数。这可以使用 jQuery.extend()
函数与返回的对象一起完成
var searchOptions = $.fn.dataTable.ext.deepLink( [
'order'
];
var defaultOptions = {
order: [[ 2, 'desc' ]]
};
$('#myTable').DataTable(
$.extend( defaultOptions, searchOptions )
);
如何运作?
既然我们知道如何使用它,如果您有兴趣了解它的工作原理,那就继续阅读。它的确非常简单!让我们首先回到我在论坛中的标准回复,即应该使用搜索字符串来设置参数值。如果我们假设整个搜索字符串将用于搜索该表(例如,/table?mySearchTerm
),我们可能会使用
$('#myTable').DataTable( {
search: {
search: location.search.replace(/^\?/, '')
}
} );
现在关键是要将搜索字符串分解为键值对。有点令人惊讶的是,浏览器中没有对此的 API,但使用 String.prototype.split
和 decodeURIComponent()
便可以轻易实现
$.fn.dataTable.ext.deepLink = function(whitelist) {
var search = location.search.replace(/^\?/, '').split('&');
var out = {};
for (var i = 0, ien = search.length; i < ien; i++) {
var pair = search[i].split('=');
var key = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
...
}
return out;
};
### Casting values
The query string can only directly hold string values (it is a string itself after all), unless we use a data schema such as JSON. JSON isn't pretty to look at in a URL, so we want to avoid that here. The type always being a string is an issue in this case as certain DataTables parameters expect other types - for example `-init displayStart` must be a `Number` and not a `String` while `-init paging` is a Boolean. As such we need to [cast](https://en.wikipedia.org/wiki/Type_conversion) the string values into their typed counterparts:
```js
if (value === 'true') {
value = true;
}
else if (value === 'false') {
value = false;
}
else if (!value.match(/[^\d]/)) {
value = value * 1;
}
else if (value.indexOf('{') === 0 || value.indexOf('[') === 0) {
// Try to JSON parse for arrays and obejcts
try {
value = $.parseJSON( value );
}
catch(e){}
}
缺点是无法将 search.search
设置为 true
,因为会因上述代码而转换为布尔值。我觉得出现这种情况的可能性比较小,但如果您遇到了,则上述代码片段需要根据您的需要进行修改。
编写嵌套值
您可能在上面的示例中注意到我们经常使用 search.search
,因为这是我认为该脚本最常使用的参数之一。但是,它的 Javascript 对象版本实际上是 { search: { search: ... } }
- 即一个嵌套对象。要从字符串表示法转换,我们可以使用 DataTables 内置的一个函数根据一个点分隔的字符串构建嵌套对象:$.fn.dataTable.ext.internal._fnSetObjectDataFn
(这是用于 columns.data
的)。这个函数不是一个记录在案的 API,但下一个主要版本会看到它被提升为这样(尽管使用了一个更容易访问的名称),因为它对于插件和附加脚本非常有用!
var setBuilder = $.fn.dataTable.ext.internal._fnSetObjectDataFn;
if (whitelist === 'all' || $.inArray(key, whitelist) !== -1) {
var setter = setBuilder(key);
setter(out, value);
}
源代码和 Git
有关该脚本的完整记录源代码,请 在 GitHub 上查找。如果您有任何增强建议,欢迎提出拉取请求!