字母輸入搜尋 - 第三部分
在本系列文章的最後一部分中,我將詳細說明如何將本系列前兩部分中建立的字母搜尋轉換為 DataTables 的功能外掛程式,並使用API 擴充方法來控制我們建立的新功能。
最終結果是 DataTables 的可自訂擴充功能,可以使用簡單的初始化,輕鬆地在任何網頁上重複使用一個或多個表格
var table = $('#example').DataTable( {
layout: {
top1: 'alphabetSearch'
}
} );
或者,如果您使用的是舊版 DataTables 1.x
var table = $('#example').DataTable( {
dom: 'Alfrtip'
} );
請注意使用 dom
來指定所使用的表格控制元素 - A
是我們新的外掛程式。這就是使用它的全部內容!
在我們深入探討程式碼之前,最終結果現在已在 DataTables CDN 上提供 (Javascript / CSS),並且下方顯示了結果表格的示範 (其功能與第二部分中建立的功能相同)。
姓名 | 職位 | 辦公室 | 年齡 | 開始日期 | 薪資 |
---|---|---|---|---|---|
Tiger Nixon | 系統架構師 | 愛丁堡 | 61 | 2011-04-25 | $320,800 |
Garrett Winters | 會計師 | 東京 | 63 | 2011-07-25 | $170,750 |
Ashton Cox | 初級技術作者 | 舊金山 | 66 | 2009-01-12 | $86,000 |
Cedric Kelly | 資深 Javascript 開發人員 | 愛丁堡 | 22 | 2012-03-29 | $433,060 |
Airi Satou | 會計師 | 東京 | 33 | 2008-11-28 | $162,700 |
Brielle Williamson | 整合專家 | 紐約 | 61 | 2012-12-02 | $372,000 |
Herrod Chandler | 銷售助理 | 舊金山 | 59 | 2012-08-06 | $137,500 |
Rhona Davidson | 整合專家 | 東京 | 55 | 2010-10-14 | $327,900 |
Colleen Hurst | Javascript 開發人員 | 舊金山 | 39 | 2009-09-15 | $205,500 |
Sonya Frost | 軟體工程師 | 愛丁堡 | 23 | 2008-12-13 | $103,600 |
Jena Gaines | 辦公室經理 | 倫敦 | 30 | 2008-12-19 | $90,560 |
Quinn Flynn | 支援主管 | 愛丁堡 | 22 | 2013-03-03 | $342,000 |
Charde Marshall | 區域總監 | 舊金山 | 36 | 2008-10-16 | $470,600 |
Haley Kennedy | 資深行銷設計師 | 倫敦 | 43 | 2012-12-18 | $313,500 |
Tatyana Fitzpatrick | 區域總監 | 倫敦 | 19 | 2010-03-17 | $385,750 |
Michael Silva | 行銷設計師 | 倫敦 | 66 | 2012-11-27 | $198,500 |
Paul Byrd | 財務長 (CFO) | 紐約 | 64 | 2010-06-09 | $725,000 |
Gloria Little | 系統管理員 | 紐約 | 59 | 2009-04-10 | $237,500 |
Bradley Greer | 軟體工程師 | 倫敦 | 41 | 2012-10-13 | $132,000 |
Dai Rios | 人事主管 | 愛丁堡 | 35 | 2012-09-26 | $217,500 |
Jenette Caldwell | 開發主管 | 紐約 | 30 | 2011-09-03 | $345,000 |
Yuri Berry | 行銷長 (CMO) | 紐約 | 40 | 2009-06-25 | $675,000 |
Caesar Vance | 售前支援 | 紐約 | 21 | 2011-12-12 | $106,450 |
Doris Wilder | 銷售助理 | 雪梨 | 23 | 2010-09-20 | $85,600 |
Angelica Ramos | 執行長 (CEO) | 倫敦 | 47 | 2009-10-09 | $1,200,000 |
Gavin Joyce | 開發人員 | 愛丁堡 | 42 | 2010-12-22 | $92,575 |
Jennifer Chang | 區域總監 | 新加坡 | 28 | 2010-11-14 | $357,650 |
Brenden Wagner | 軟體工程師 | 舊金山 | 28 | 2011-06-07 | $206,850 |
Fiona Green | 營運長 (COO) | 舊金山 | 48 | 2010-03-11 | $850,000 |
Shou Itou | 區域行銷 | 東京 | 20 | 2011-08-14 | $163,000 |
Michelle House | 整合專家 | 雪梨 | 37 | 2011-06-02 | $95,400 |
Suki Burks | 開發人員 | 倫敦 | 53 | 2009-10-22 | $114,500 |
Prescott Bartlett | 技術作者 | 倫敦 | 27 | 2011-05-07 | $145,000 |
Gavin Cortez | 團隊領導 | 舊金山 | 22 | 2008-10-26 | $235,500 |
Martena Mccray | 售後支援 | 愛丁堡 | 46 | 2011-03-09 | $324,050 |
Unity Butler | 行銷設計師 | 舊金山 | 47 | 2009-12-09 | $85,675 |
Howard Hatfield | 辦公室經理 | 舊金山 | 51 | 2008-12-16 | $164,500 |
Hope Fuentes | 秘書 | 舊金山 | 41 | 2010-02-12 | $109,850 |
Vivian Harrell | 財務長 | 舊金山 | 62 | 2009-02-14 | $452,500 |
Timothy Mooney | 辦公室經理 | 倫敦 | 37 | 2008-12-11 | $136,200 |
Jackson Bradshaw | 董事 | 紐約 | 65 | 2008-09-26 | $645,750 |
Olivia Liang | 支援工程師 | 新加坡 | 64 | 2011-02-03 | $234,500 |
Bruno Nash | 軟體工程師 | 倫敦 | 38 | 2011-05-03 | $163,500 |
Sakura Yamamoto | 支援工程師 | 東京 | 37 | 2009-08-19 | $139,575 |
Thor Walton | 開發人員 | 紐約 | 61 | 2013-08-11 | $98,540 |
Finn Camacho | 支援工程師 | 舊金山 | 47 | 2009-07-07 | $87,500 |
Serge Baldwin | 資料協調員 | 新加坡 | 64 | 2012-04-09 | $138,575 |
Zenaida Frank | 軟體工程師 | 紐約 | 63 | 2010-01-04 | $125,250 |
Zorita Serrano | 軟體工程師 | 舊金山 | 56 | 2012-06-01 | $115,000 |
Jennifer Acosta | 初級 Javascript 開發人員 | 愛丁堡 | 43 | 2013-02-01 | $75,650 |
Cara Stevens | 銷售助理 | 紐約 | 46 | 2011-12-06 | $145,600 |
Hermione Butler | 區域總監 | 倫敦 | 47 | 2011-03-21 | $356,250 |
Lael Greer | 系統管理員 | 倫敦 | 21 | 2009-02-27 | $103,500 |
Jonas Alexander | 開發人員 | 舊金山 | 30 | 2010-07-14 | $86,500 |
Shad Decker | 區域總監 | 愛丁堡 | 51 | 2008-11-13 | $183,000 |
Michael Bruce | Javascript 開發人員 | 新加坡 | 29 | 2011-06-27 | $183,000 |
Donna Snider | 客戶支援 | 紐約 | 27 | 2011-01-25 | $112,000 |
姓名 | 職位 | 辦公室 | 年齡 | 開始日期 | 薪資 |
值得注意的是,我將假設您熟悉本系列第一部分和第二部分中開發的程式碼。由於此功能外掛程式所需的大部分程式碼已在這些文章中開發,我將縮短這些程式碼區塊。這篇文章只是關於將程式碼重新整理成 DataTables 的可重複使用外掛程式。
功能外掛程式
手冊的功能外掛程式部分詳細說明瞭如何為 DataTables 建立功能外掛程式。基本概念是,我們需要註冊一個新的功能外掛程式,該外掛程式可以透過 $.fn.dataTable.ext.feature
陣列與 dom
一起使用。我們提供要註冊的字母和一個回呼函式,當外掛程式要用於 DataTable 時會執行該函式 - 此回呼必須傳回要插入文件中以進行控制的節點,在本例中為字母搜尋列。
$.fn.dataTable.ext.feature.push( {
fnInit: function ( settings ) {
var search = new $.fn.dataTable.AlphabetSearch( settings );
return search.node();
},
cFeature: 'A'
} );
在上面的程式碼中,我們註冊了字元 A
並建立一個新的 $.fn.dataTable.AlphabetSearch
實例,從其自身的 API node()
方法傳回節點。
$.fn.dataTable.AlphabetSearch
在我們的程式碼中是新的,但它只是先前開發的用於建立字母搜尋輸入節點的程式碼的封裝
$.fn.dataTable.AlphabetSearch = function ( context ) {
var table = new $.fn.dataTable.Api( context );
var alphabet = $('<div class="alphabet"/>');
// Bin the data and create the alphabet search input element
...
// API method to get the alphabet container node
this.node = function () {
return alphabet;
};
};
請注意新增了 node()
API 方法,可用於取得容器節點,如以上 DataTables 功能的註冊中所做的那樣。
替代初始化
值得指出的是,字母搜尋也可以直接使用 new $.fn.dataTable.AlphabetSearch()
初始化,而不是使用 dom
選項。如果您願意,這可以提高靈活性並控制您插入字母列的位置
var table = $('#myTable').DataTable();
var search = new $.fn.dataTable.AlphabetSearch();
$( search.node() ).appendTo( ... ); // insert into document
搜尋外掛程式更新
先前,搜尋外掛程式使用變數 _alphabetSearch
來判斷要搜尋的字母,但是該變數並未隔離到單一表格 - 它會套用至頁面上的所有表格。這不適用於可重複使用的元件,因此我們需要使用不同的方法來儲存要搜尋的字母。
為此,我們可以利用 DataTables 設定物件,該物件對於頁面上的每個表格都是全域唯一的 (設定物件在許多 API 文件中稱為「內容」)。只需將我們的參數附加到設定物件,我們就可以始終存取該表格的參數。請考慮以下對我們在第一部分中開發的搜尋外掛程式的更新
$.fn.dataTable.ext.search.push( function ( context, searchData ) {
// Ensure that there is a search applied to this table before running it
if ( ! context.alphabetSearch ) {
return true;
}
if ( searchData[0].charAt(0) === context.alphabetSearch ) {
return true;
}
return false;
} );
變更只是使用 context.alphabetSearch
而不是 _alphabetSearch
。現在要觸發搜尋,我們只需要設定該參數,這就是 API 外掛程式的用武之地。
API 外掛程式
API 外掛程式可以擴充 DataTables 提供的預設 API 方法集,並且在這種情況下,我們希望新增為每個表格設定 alphabetSearch
參數的功能。我們可以透過以下方式輕鬆做到這一點
$.fn.dataTable.Api.register( 'alphabetSearch()', function ( searchTerm ) {
this.iterator( 'table', function ( context ) {
context.alphabetSearch = searchTerm;
} );
return this;
} );
在上述程式碼中,使用 iterator()
方法來迴圈 API 實例內容中的每個表格,並設定搜尋字詞。儘管我們的功能外掛程式並未使用 DataTables API 的多表格層面,但完全可以使用 $('table.dataTable').DataTable().alphabetSearch( 'A' );
在頁面上的所有表格中搜尋 A
,因為使用了上述 iterator()
。
為了完整起見,我們也建立一個可用於重新分組資料的方法 - 更新每個字母滑鼠移過時顯示的計數
$.fn.dataTable.Api.register( 'alphabetSearch.recalc()', function ( searchTerm ) {
this.iterator( 'table', function ( context ) {
draw(
new $.fn.dataTable.Api( context ),
$('div.alphabet', this.table().container()) );
);
} );
return this;
} );
這會使用 draw()
方法,該方法只是封裝先前開發的繪製程式碼的函式。它會傳遞給目前表格的 API 實例和相關表格的字母搜尋 DOM 節點。
最終程式碼
我們已經到達 DataTables 擴充功能世界的尾聲,我希望您發現這是一個有用的介紹,可以瞭解如何建立可重複使用的外掛程式,以根據您的需求自訂 DataTables。
一如既往,非常歡迎對此和 DataTables 的任何其他方面提供回饋!
本系列文章中開發的最終程式碼如下所示,並且可在 DataTables CDN 上取得 (Javascript / CSS)。
(function(){
// Search function
$.fn.dataTable.Api.register( 'alphabetSearch()', function ( searchTerm ) {
this.iterator( 'table', function ( context ) {
context.alphabetSearch = searchTerm;
} );
return this;
} );
// Recalculate the alphabet display for updated data
$.fn.dataTable.Api.register( 'alphabetSearch.recalc()', function ( searchTerm ) {
this.iterator( 'table', function ( context ) {
draw(
new $.fn.dataTable.Api( context ),
$('div.alphabet', this.table().container())
);
} );
return this;
} );
// Search plug-in
$.fn.dataTable.ext.search.push( function ( context, searchData ) {
// Ensure that there is a search applied to this table before running it
if ( ! context.alphabetSearch ) {
return true;
}
if ( searchData[0].charAt(0) === context.alphabetSearch ) {
return true;
}
return false;
} );
// Private support methods
function bin ( data ) {
var letter, bins = {};
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
letter = data[i].charAt(0).toUpperCase();
if ( bins[letter] ) {
bins[letter]++;
}
else {
bins[letter] = 1;
}
}
return bins;
}
function draw ( table, alphabet )
{
alphabet.empty();
alphabet.append( 'Search: ' );
var columnData = table.column(0).data();
var bins = bin( columnData );
$('<span class="clear active"/>')
.data( 'letter', '' )
.data( 'match-count', columnData.length )
.html( 'None' )
.appendTo( alphabet );
for ( var i=0 ; i<26 ; i++ ) {
var letter = String.fromCharCode( 65 + i );
$('<span/>')
.data( 'letter', letter )
.data( 'match-count', bins[letter] || 0 )
.addClass( ! bins[letter] ? 'empty' : '' )
.html( letter )
.appendTo( alphabet );
}
$('<div class="alphabetInfo"></div>')
.appendTo( alphabet );
}
$.fn.dataTable.AlphabetSearch = function ( context ) {
var table = new $.fn.dataTable.Api( context );
var alphabet = $('<div class="alphabet"/>');
draw( table, alphabet );
// Trigger a search
alphabet.on( 'click', 'span', function () {
alphabet.find( '.active' ).removeClass( 'active' );
$(this).addClass( 'active' );
table
.alphabetSearch( $(this).data('letter') )
.draw();
} );
// Mouse events to show helper information
alphabet
.on( 'mouseenter', 'span', function () {
alphabet
.find('div.alphabetInfo')
.css( {
opacity: 1,
left: $(this).position().left,
width: $(this).width()
} )
.html( $(this).data('match-count') );
} )
.on( 'mouseleave', 'span', function () {
alphabet
.find('div.alphabetInfo')
.css('opacity', 0);
} );
// API method to get the alphabet container node
this.node = function () {
return alphabet;
};
};
$.fn.DataTable.AlphabetSearch = $.fn.dataTable.AlphabetSearch;
// Register a search plug-in
$.fn.dataTable.ext.feature.push( {
fnInit: function ( settings ) {
var search = new $.fn.dataTable.AlphabetSearch( settings );
return search.node();
},
cFeature: 'A'
} );
}());