輸入分頁外掛
DataTables 2 引入了功能的概念,這些功能是表格控制和資訊元件,它們使用layout
選項放置在表格周圍。有一些內建的功能,以及一些擴充套件會加入自己的功能,但我想藉由這篇部落格文章來介紹一個新的 DataTables 功能外掛,展示它的功能,並詳細說明製作 DataTables 功能外掛有多麼容易。
我將在這裡介紹的功能外掛稱為 InputPaging,它提供一個控制項,可以取代內建的分頁
功能。它的功能包括:
- 向終端使用者顯示目前頁碼
- 允許終端使用者輸入他們想要檢視的頁碼
- 可選的上一個/下一個按鈕
- 可選的第一個/最後一個按鈕
- 可選的總頁數計數
- 自動與 DataTables 的預設樣式、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'
}
});
請注意,此範例使用新的分頁控制項取代預設的分頁
控制項,該控制項通常位於表格的 bottomEnd
。由於layout
的運作方式,可以讓此控制項同時顯示在表格的上方和下方,或者,如果您願意,也可以同時顯示預設的分頁功能和此控制項!
來源
此外掛的來源可在DataTables 外掛 git 儲存庫中取得,並以 MIT 授權發佈。要直接包含在您頁面上的發佈檔案可在 DataTables CDN 上取得
如果您使用 bundler,則此外掛程式可在 npm 上以 datatables.net-feature-inputpaging
的名稱取得。若要與 ES Modules 一起使用,只需包含該套件,它就會將自己註冊為可用的功能
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
,控制是否在目前頁碼的input
之後立即顯示/ {pages}
文字。
若要設定選項,請將 inputPaging
選項用作layout
中的物件 - 例如:
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 的預設樣式,因此我們需要使用與分頁
控制項相同的結構。這就是我們想要的:
<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>
在 vanilla 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;
}
然後建立「第一個」按鈕可能會如下所示。請注意使用 i18n
來取得為第一個分頁按鈕定義的語言字串。這確保與 DataTable 的現有選項完全整合。此外,page()
用於事件處理器中以觸發頁面變更。
let first = createElement(
'button',
'dt-paging',
api.i18n('oPaginate.sFirst', '\u00AB'),
() => api.page('first').draw(false)
);
每個按鈕都會被建立,然後附加到父元素,也就是從功能建立函式傳回的元素。儘管使用了輔助函式,但此程式碼仍然相當冗長,因此為了簡潔起見,請參閱此處的程式碼。
輸入事件處理器
這才是開始變得更有趣的地方。只有數字值與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
事件,此時我們需要使用以下動作更新我們的控制項:
- 視覺上指示是否有任何按鈕被停用(例如,當已經在第一頁時,點擊「第一個」按鈕沒有意義!)。這只需從上面建立的按鈕新增或移除
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 結構,每個樣式架構的 DOM 結構略有不同。
建立您自己的外掛程式
如果您受到啟發並建立了您自己的功能外掛程式,請聯絡我們並與社群分享!我很想看看您可以做出什麼。