2014 年 8 月 26 日 星期二

字母輸入搜尋 - 第一部分

搜尋是 DataTables 的核心功能 - 事實上,它是 2007 年在程式碼中實作的第一個功能,因為它對於 DataTables 的設計目的至關重要:讓使用者能夠快速輕鬆地在複雜的資料集中找到資訊。自最初的工作以來,DataTables 的搜尋選項已經有了很大的進步,並透過 search() 方法和其他方法提供了一系列的選項。

然而,您通常會希望自訂 DataTables 的搜尋選項,以符合您自己的需求。這可能就像提供一個完全符合您網站一般使用者體驗的自訂輸入一樣簡單,或者您可能想要使用複雜的搜尋演算法。

為了滿足此需求,DataTables 提供了一個自訂搜尋 API,可用於執行您想要的任何搜尋邏輯。在這個分為三個部分的文章系列中,我將介紹這個 API,展示如何使用它,並提供符合您特定需求的自訂搜尋功能。作為一個實際範例,本系列將開發一個字母搜尋欄,向您展示 DataTables 外掛程式系統的各個方面是如何運作的。

  • 第一部分(這篇文章):介紹自訂搜尋並展示一個可點擊的字母篩選器
  • 第二部分:新增使用者資訊,顯示篩選器中每個選項的搜尋結果數量
  • 第三部分:建立 DataTables 的功能外掛程式,整合先前開發的程式碼以實現重複使用彈性。

字母搜尋

讓我們從最後開始,看看我們在這篇文章中將要創建的內容 - 一個在 DataTable 上方的字母列表,當點擊時,將會啟動表格搜尋,尋找第一列中以點擊字母開頭的資料

姓名職位辦公室年齡開始日期薪水
Tiger Nixon系統架構師愛丁堡612011-04-25$320,800
Garrett Winters會計師東京632011-07-25$170,750
Ashton Cox初級技術作家舊金山662009-01-12$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡222012-03-29$433,060
Airi Satou會計師東京332008-11-28$162,700
Brielle Williamson整合專員紐約612012-12-02$372,000
Herrod Chandler銷售助理舊金山592012-08-06$137,500
Rhona Davidson整合專員東京552010-10-14$327,900
Colleen HurstJavascript 開發人員舊金山392009-09-15$205,500
Sonya Frost軟體工程師愛丁堡232008-12-13$103,600
Jena Gaines辦公室經理倫敦302008-12-19$90,560
Quinn Flynn支援主管愛丁堡222013-03-03$342,000
Charde Marshall區域總監舊金山362008-10-16$470,600
Haley Kennedy資深行銷設計師倫敦432012-12-18$313,500
Tatyana Fitzpatrick區域總監倫敦192010-03-17$385,750
Michael Silva行銷設計師倫敦662012-11-27$198,500
Paul Byrd財務長 (CFO)紐約642010-06-09$725,000
Gloria Little系統管理員紐約592009-04-10$237,500
Bradley Greer軟體工程師倫敦412012-10-13$132,000
Dai Rios人事主管愛丁堡352012-09-26$217,500
Jenette Caldwell開發主管紐約302011-09-03$345,000
Yuri Berry行銷長 (CMO)紐約402009-06-25$675,000
Caesar Vance售前支援紐約212011-12-12$106,450
Doris Wilder銷售助理雪梨232010-09-20$85,600
Angelica Ramos執行長 (CEO)倫敦472009-10-09$1,200,000
Gavin Joyce開發人員愛丁堡422010-12-22$92,575
Jennifer Chang區域總監新加坡282010-11-14$357,650
Brenden Wagner軟體工程師舊金山282011-06-07$206,850
Fiona Green營運長 (COO)舊金山482010-03-11$850,000
Shou Itou區域行銷東京202011-08-14$163,000
Michelle House整合專員雪梨372011-06-02$95,400
Suki Burks開發人員倫敦532009-10-22$114,500
Prescott Bartlett技術作家倫敦272011-05-07$145,000
Gavin Cortez團隊領導舊金山222008-10-26$235,500
Martena Mccray售後支援愛丁堡462011-03-09$324,050
Unity Butler行銷設計師舊金山472009-12-09$85,675
Howard Hatfield辦公室經理舊金山512008-12-16$164,500
Hope Fuentes秘書舊金山412010-02-12$109,850
Vivian Harrell財務主管舊金山622009-02-14$452,500
Timothy Mooney辦公室經理倫敦372008-12-11$136,200
Jackson Bradshaw總監紐約652008-09-26$645,750
Olivia Liang支援工程師新加坡642011-02-03$234,500
Bruno Nash軟體工程師倫敦382011-05-03$163,500
Sakura Yamamoto支援工程師東京372009-08-19$139,575
Thor Walton開發人員紐約612013-08-11$98,540
Finn Camacho支援工程師舊金山472009-07-07$87,500
Serge Baldwin資料協調員新加坡642012-04-09$138,575
Zenaida Frank軟體工程師紐約632010-01-04$125,250
Zorita Serrano軟體工程師舊金山562012-06-01$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡432013-02-01$75,650
Cara Stevens銷售助理紐約462011-12-06$145,600
Hermione Butler區域總監倫敦472011-03-21$356,250
Lael Greer系統管理員倫敦212009-02-27$103,500
Jonas Alexander開發人員舊金山302010-07-14$86,500
Shad Decker區域總監愛丁堡512008-11-13$183,000
Michael BruceJavascript 開發人員新加坡292011-06-27$183,000
Donna Snider客戶支援紐約272011-01-25$112,000
姓名職位辦公室年齡開始日期薪水

搜尋外掛程式

DataTables 的搜尋外掛程式會附加到 $.fn.dataTable.ext.search 陣列。只需將一個函式 push() 到此陣列上,DataTables 就會在需要執行搜尋操作時針對表格中的每一列執行該函式。然後,該函式應傳回 truefalse,以向 DataTables 指示該列是否應包含在結果集中 (true) 或不應包含 (false)。

在字母搜尋的情況下,我們只想檢查第一列資料的第一個字母(可以從傳遞到函式的第二個參數中取得,並結合 charAt() 方法)與一個變數進行比較,該變數會儲存使用者已啟動搜尋的字元(稱之為 _alphabetSearch)。

這給了我們這個簡單的小函式

var _alphabetSearch;

$.fn.dataTable.ext.search.push( function ( settings, searchData ) {
    if ( ! _alphabetSearch ) { // No search term - all results shown
        return true;
    }

    if ( searchData[0].charAt(0) === _alphabetSearch ) {
        return true;
    }

    return false;
} );

如果您有興趣了解有關此 API 的更多資訊,DataTables 手冊 包含有關 搜尋外掛程式 API 的詳細資訊。

介面

我們在此要呈現給最終使用者的介面實際上非常簡單。只是一個 A-Z 字母列表。這裡沒有 DataTables 特有的程式碼,只有簡單的 jQuery 操作 DOM 來建立一個 div 元素,其中包含一個 span 列表,每個字母一個,因此我不會詳細介紹此程式碼,但有幾個重點值得注意

  • 包含一個選項來清除搜尋詞,允許顯示表格中的所有條目。
  • 使用 String.formCharCode 將 ASCII 程式碼轉換為字母。
  • 資料屬性 letter 用於儲存要用於搜尋詞的字母。
// DataTables initialisation
var table = $('#example').DataTable();

var alphabet = $('<div class="alphabet"/>').append( 'Search: ' );

$('<span class="clear active"/>')
    .data( 'letter', '' )
    .html( 'None' )
    .appendTo( alphabet );

for ( var i=0 ; i<26 ; i++ ) {
    var letter = String.fromCharCode( 65 + i );

    $('<span/>')
        .data( 'letter', letter )
        .html( letter )
        .appendTo( alphabet );
}

alphabet.insertBefore( table.table().container() );

以上僅適用於拉丁文字中使用的字母的簡單範例,但可以輕鬆擴展為使用任何其他字母表中的字元,或包含數值。

行為

為了啟動搜尋,我們使用一個 標準 jQuery $().on() 點擊處理器來監聽點擊事件。監聽器將讀取元素的 letter 資料屬性,並將其指派給我們在上面的搜尋函式中定義的 _alphabetSearch 變數,然後使用 draw() 重新繪製表格,並將新的搜尋詞納入考量。它還進行了一些類別操作,以視覺化顯示哪個元素是活動的搜尋詞。

alphabet.on( 'click', 'span', function () {
    alphabet.find( '.active' ).removeClass( 'active' );
    $(this).addClass( 'active' );

    _alphabetSearch = $(this).data('letter');
    table.draw();
} );

樣式

我們的字母列表有一個非常簡單的 DOM 結構,由一個 div 和其中的 span 元素組成。為了整齊地顯示,我們可以使用 CSS display: table 屬性,讓字母以彈性寬度、整齊排列的網格顯示。還新增了一些其他樣式,僅為最終使用者提供視覺回饋。

div.alphabet {
    display: table;
    width: 100%;
    margin-bottom: 1em;
}

div.alphabet span {
    display: table-cell;
    color: #3174c7;
    cursor: pointer;
    text-align: center;
    width: 3.5%
}

div.alphabet span:hover {
    text-decoration: underline;
}

div.alphabet span.active {
    color: black;
}

完整程式碼

上面顯示的 Javascript 是完整的,但如果您想要複製貼上的解決方案,而不是組裝程式碼,下面顯示了此範例使用的整個程式碼區塊

var _alphabetSearch = '';

$.fn.dataTable.ext.search.push( function ( settings, searchData ) {
    if ( ! _alphabetSearch ) {
        return true;
    }

    if ( searchData[0].charAt(0) === _alphabetSearch ) {
        return true;
    }

    return false;
} );


$(document).ready(function() {
    var table = $('#example').DataTable();

    var alphabet = $('<div class="alphabet"/>').append( 'Search: ' );

    $('<span class="clear active"/>')
        .data( 'letter', '' )
        .html( 'None' )
        .appendTo( alphabet );

    for ( var i=0 ; i<26 ; i++ ) {
        var letter = String.fromCharCode( 65 + i );

        $('<span/>')
            .data( 'letter', letter )
            .html( letter )
            .appendTo( alphabet );
    }

    alphabet.insertBefore( table.table().container() );

    alphabet.on( 'click', 'span', function () {
        alphabet.find( '.active' ).removeClass( 'active' );
        $(this).addClass( 'active' );

        _alphabetSearch = $(this).data('letter');
        table.draw();
    } );
} );