输入分页插件
DataTables 2 引入了 功能 的概念,这些功能是与 layout
选项一起放置在表格周围的表格控件和信息组件。有几个内置功能,一些 扩展 添加了它们自己的功能,但我想利用这篇博文来介绍 DataTables 的一个新型功能插件,展示它的功能,并且详细说明为 DataTables 制作功能插件有多么容易。
这里要介绍的功能插件被称为 InputPaging,它提供一个控件,可以替换内置 paging
功能。它的功能包括
- 向最终用户展示当前页码
- 允许最终用户键入他们想要查看的页码
- 可选的上一个/下一个按钮
- 可选的第一个/最后一个按钮
- 可选的总页数
- 自动与 DataTable 的默认样式、Bootstrap 3/4/5、Bulma、Foundation、jQuery UI 和 FomanticUI 集成。
这是实际使用中的一个示例(InputPaging 控件位于表格的右下角)
姓名 | 职位 | 办公地点 | 薪水 |
---|---|---|---|
Tiger Nixon | 系统架构师 | 爱丁堡 | $320,800 |
Garrett Winters | 会计师 | 东京 | $170,750 |
Ashton Cox | 初级技术作者 | 旧金山 | $86,000 |
Cedric Kelly | 高级 Javascript 开发者 | 爱丁堡 | $433,060 |
Airi Satou | 会计师 | 东京 | $162,700 |
Brielle Williamson | 集成专家 | 纽约 | $372,000 |
Herrod Chandler | 销售助理 | 旧金山 | $137,500 |
Rhona Davidson | 集成专家 | 东京 | $327,900 |
Colleen Hurst | Javascript 开发者 | 旧金山 | $205,500 |
Sonya Frost | 软件工程师 | 爱丁堡 | $103,600 |
Jena Gaines | 办公室经理 | 伦敦 | $90,560 |
Quinn Flynn | 支持主管 | 爱丁堡 | $342,000 |
Charde Marshall | 区域总监 | 旧金山 | $470,600 |
Haley Kennedy | 高级营销设计师 | 伦敦 | $313,500 |
Tatyana Fitzpatrick | 区域总监 | 伦敦 | $385,750 |
Michael Silva | 营销设计师 | 伦敦 | $198,500 |
Paul Byrd | 首席财务官 (CFO) | 纽约 | $725,000 |
Gloria Little | 系统管理员 | 纽约 | $237,500 |
Bradley Greer | 软件工程师 | 伦敦 | $132,000 |
Dai Rios | 人事主管 | 爱丁堡 | $217,500 |
Jenette Caldwell | 开发主管 | 纽约 | $345,000 |
Yuri Berry | 首席营销官 (CMO) | 纽约 | $675,000 |
Caesar Vance | 售前支持 | 纽约 | $106,450 |
Doris Wilder | 销售助理 | 悉尼 | $85,600 |
Angelica Ramos | 首席执行官 (CEO) | 伦敦 | $1,200,000 |
Gavin Joyce | 开发者 | 爱丁堡 | $92,575 |
Jennifer Chang | 区域总监 | 新加坡 | $357,650 |
Brenden Wagner | 软件工程师 | 旧金山 | $206,850 |
Fiona Green | 首席运营官 (COO) | 旧金山 | $850,000 |
Shou Itou | 区域营销 | 东京 | $163,000 |
Michelle House | 集成专家 | 悉尼 | $95,400 |
Suki Burks | 开发者 | 伦敦 | $114,500 |
Prescott Bartlett | 技术作者 | 伦敦 | $145,000 |
Gavin Cortez | 团队主管 | 旧金山 | $235,500 |
Martena Mccray | 售后支持 | 爱丁堡 | $324,050 |
Unity Butler | 营销设计师 | 旧金山 | $85,675 |
Howard Hatfield | 办公室经理 | 旧金山 | $164,500 |
Hope Fuentes | 秘书 | 旧金山 | $109,850 |
Vivian Harrell | 财务主管 | 旧金山 | $452,500 |
Timothy Mooney | 办公室经理 | 伦敦 | $136,200 |
Jackson Bradshaw | 总监 | 纽约 | $645,750 |
Olivia Liang | 支持工程师 | 新加坡 | $234,500 |
Bruno Nash | 软件工程师 | 伦敦 | $163,500 |
Sakura Yamamoto | 支持工程师 | 东京 | $139,575 |
Thor Walton | 开发者 | 纽约 | $98,540 |
Finn Camacho | 支持工程师 | 旧金山 | $87,500 |
Serge Baldwin | 数据协调员 | 新加坡 | $138,575 |
Zenaida Frank | 软件工程师 | 纽约 | $125,250 |
Zorita Serrano | 软件工程师 | 旧金山 | $115,000 |
Jennifer Acosta | 初级 JavaScript 开发人员 | 爱丁堡 | $75,650 |
Cara Stevens | 销售助理 | 纽约 | $145,600 |
Hermione Butler | 区域总监 | 伦敦 | $356,250 |
Lael Greer | 系统管理员 | 伦敦 | $103,500 |
Jonas Alexander | 开发者 | 旧金山 | $86,500 |
Shad Decker | 区域总监 | 爱丁堡 | $183,000 |
Michael Bruce | Javascript 开发者 | 新加坡 | $183,000 |
Donna Snider | 客服 | 纽约 | $112,000 |
用法
在详细介绍如何创建你自己的自定义功能插件之前,让我们探索如何使用 InputPaging 插件。
初始化
此示例的初始化非常简单
new DataTable('#inputPaging', {
layout: {
bottomEnd: 'inputPaging'
}
});
请注意,此示例在新分页控件的底部使用新分页控件替换默认的 paging
控件。由于 layout
的工作原理,因此有可能在表格的上方和下方同时显示此控件,或者根据需要显示默认分页功能以及此功能!
来源
此插件的源代码在 DataTables 插件Git 仓库 中提供,并根据 MIT 许可证发布。可直接在你的页面中包含的分发文件在 DataTables CDN 上提供
如果您正在使用打包器,则此插件在 npm 上可通过 datatables.net-feature-inputpaging
获得。要将它与 ES 模块一起使用,只需包含该软件包,它便会将自身注册为可用功能
import DataTable from 'datatables.net-dt';
import 'datatables.net-feature-inputpaging';
new DataTable('#example', {
layout: {
bottomEnd: 'inputPaging'
}
});
此 StackBlitz 示例演示了如何在 Typescript + Vite 构建环境中使用此新插件。
选项
inputPaging
功能有三个选项
boolean
firstLast
控制是否显示第一个和最后一个按钮boolean
previousNext
控制是否显示上一个和下一个按钮boolean
pageOf
控制是否在输入当前页码后立即显示/ {pages}
文本。
要设置选项,请在 layout
中使用 inputPaging
选项作为对象 - 例如
new DataTable('#example', {
layout: {
bottomEnd: {
inputPaging: {
pageOf: false
}
}
}
});
创建功能插件
为 DataTables 创建功能插件非常简单 - 使用 DataTable.feature.register()
静态方法来使用 DataTables 注册你的功能。参考文档提供了方法的全部详细信息,但从本质上来说,它需要两个参数;功能名称(即如何引用 layout
中的功能),以及一个函数来创建对应功能的 DOM 元素和事件监听器。此函数应返回一个 DOM 节点,并传入两个参数 - DataTable 设置对象以及功能选项。
使用代码表示更容易理解
DataTable.feature.register('myToolbar', function (settings, opts) {
// Define defaults
let options = Object.assign({
option1: false,
option2: false
}, opts);
let container = document.createElement('div');
// do something with the options and container
// ...
return container;
});
就是这样 - 你已经创建了 DataTables 功能插件!现在,让我们探讨如何构建分页控件。
DOM 元素
我们需要创建具有事件处理程序的多个 DOM 元素。对于此处讨论的部分,我们使用 DataTables 的默认样式处理,因此我们需要使用与 paging
控件相同的结构。这是我们想要的部分
<div class="dt-inputpaging dt-paging">
<button class="dt-paging-button disabled">«</button>
<button class="dt-paging-button disabled">‹</button>
<div class="dt-paging-input">
<input class="" type="text" inputmode="numeric" pattern="[0-9]*" style="width: 3ch;">
<span class=""> / 6</span>
</div>
<button class="dt-paging-button">›</button>
<button class="dt-paging-button">»</button>
</div>
在纯粹的 JS 中创建 DOM 节点总是会生成冗余的代码操作,因此我们为其创建一个辅助函数
/**
* Create a new element
*
* @param tag Tag name
* @param className Class to assign
* @param text Text to show in the element
* @param fn Click event handler
* @returns Element
*/
function createElement(tag, className, text, fn) {
var el = document.createElement(tag);
if (className) {
el.className = className;
}
if (text) {
el.textContent = text;
}
if (fn) {
el.addEventListener('click', fn);
}
return el;
}
然后创建“first”按钮可能类似于以下内容。请注意 i18n
用途,以便获取为第一个分页按钮定义的语言字符串。这确保了与 DataTable 的现有选项完全集成。此外,page()
在事件处理程序中用于触发页面更改。
let first = createElement(
'button',
'dt-paging',
api.i18n('oPaginate.sFirst', '\u00AB'),
() => api.page('first').draw(false)
);
每个按钮都创建,然后附加到父元素,它从特征创建函数返回。尽管使用了辅助函数,此代码仍然相当冗余,因此为了简洁,请参见 此处代码。
Input 事件处理程序
这开始变得越来越有趣。只有数字值在 input
元素中具有任何相关性,因此我们可以使用事件处理程序来禁用终端用户输入非数字字符
// Block characters other than numbers
input.addEventListener('keypress', function (e) {
if (e.charCode < 48 || e.charCode > 57) {
e.preventDefault();
}
});
我们还希望在终端用户在 input
中输入新数字时执行两个操作。第一个显而易见 - 我们需要使用 page()
将 DataTable 的显示页面更改为新数字(它具有内置修正功能,如果终端用户输入不存在的页面)。
第二个操作是调整 input
的宽度以适应内容。这对终端用户很有用,因为它允许他们看到完整的页码,而无需占用超出所需宽度的范围(这一点很重要,因为它允许表中有数百万行)。为此,我们使用带 ch
单元 的字符串中字符数,这是 0
的宽度(类似于 em
,但适用于数字!)
// On new value, redraw the table
input.addEventListener('input', function () {
if (input.value) {
api.page(input.value - 1).draw(false);
}
// Auto adjust the width so the content is visible
input.style.width = (input.value.length + 2) + 'ch';
});
DataTables 事件
最后,当 DataTable 绘制时,它会发出 draw
事件,在此事件中我们需要使用以下操作更新控件
- 可视化指示任何按钮是否已禁用(例如,当已在第一页时没有必要允许单击“First”按钮!)。这只需向上面创建的按钮添加或删除
disabled
类即可完成。page.info()
方法用于获取用于这些逻辑检查的数据。 - 接下来,如果外部操作更改了当前页面(例如,搜索将重置分页),我们需要将新值写入
input
,以便终端用户可以看到他们所在的页面。 - 最后,总页码指示器需要更新,同样使用来自
page.info()
的信息。
api.on('draw', () => {
let info = api.page.info();
// Update the classes for the "jump" buttons to show what is available
first.classList.toggle('disabled', info.page === 0);
previous.classList.toggle('disabled', info.page === 0);
next.classList.toggle('disabled', info.page === info.pages-1);
last.classList.toggle('disabled', info.page === info.pages-1);
// Set the new page value into the input box
if (input.value !== info.page + 1) {
input.value = info.page + 1;
}
// Show how many pages there are
of.textContent = ' / ' + info.pages;
});
才刚刚开始
可以在 此处 找到上面构建的代码的完整列表。您可能已经注意到,此代码并未考虑 DataTables 支持的不同样式框架,例如 Bootstrap 和 Bulma。为了使此次讨论更加容易管理,我已经简化了用于全功能插件的实际代码!如果您感兴趣,请查看 此插件的源代码 - 关键是如何处理 DOM 结构,它因每个样式框架而异。
创建您自己的插件
如果您深受启发并创建了自己的 Feature 插件,请联系我们,并与社区分享!我很想看看您能做出什么。