【Bootstrap】 typeahead自動補全

typeahead

這篇文章記錄了我在使用typeahead的一些問題,不是很全,可是基本夠用。html

Bootstrap提供typeahead組件來完成自動補全功能。ajax

兩種用法:

直接給標籤添加屬性

<input type="text" data-provide="typeahead">

經過設置autocomplete="off"來關閉瀏覽器自帶的自動補全功能,以防跟咱們的產生衝突。  bootstrap

經過JavaScript

調用$('.typeahead').typeahead()數組

typeahead()詳解

參考官方README和其餘一些博客的資料,能夠了解typeahead函數能夠接受的一些參數,這些參數能夠經過指定標籤屬性來傳遞,也能夠直接在JavaScript中給出。對於標籤屬性傳遞參數來講,須要在參數前加上data-,例如data-source="".瀏覽器

下表爲官方README文檔中參數表格的翻譯版本:app

Name Type Default Description
source array, function []

用來查詢的數據源。能夠是數組或字符串,一個帶有name屬性的JSON對象的數組集合,或者一個函數。函數能夠接受兩個參數,query表明輸入框中你的輸入值(即查詢值),process回調函數。The function may be used synchronously by returning the data source directly or asynchronously via the process callback's single argument.dom

items number 8 下拉選項中出現條目的最大數量。也能夠設置爲「all」
minLength number 1 出發下拉提示的最小長度字符串。能夠設置爲0,即便沒有填寫任何內容,也會出現提示。
showHintOnFocus boolean or "all" false 當輸入框得到焦點時馬上顯示提示。若是設置爲true,顯示全部匹配項。若是設置爲「all」,顯示全部提示,並不會按照當前文本過濾。當你須要一個組合框(Combo Box,由文本框和下拉框組成)功能時,能夠考慮這個。
scrollHeight number, function 0 Number of pixels the scrollable parent container scrolled down (scrolled out the viewport).
matcher function case insensitive 該函數用來肯定匹配條目的規則。接受一個參數,item用於測試查詢字符串是否匹配。經過當前查詢字符串this.query。若是相匹配則返回true
sorter function exact match,
case sensitive,
case insensitive
該函數用來對結果進行排序。接受一個參數items而且具備typeahead實例的做用域,經過this.query獲得當前查詢。
updater function returns selected item 該函數用來返回選中的條目。接受一個item參數而且具備typeahead實例的做用域。
highlighter function highlights all default matches 用來高亮自動補全的結果。接受一個item參數而且擁有typeahead實例的做用域。應該返回html
displayText function item.name || item 用來獲得數據源的條目的文本表示。接受一個item參數而且擁有typeahead實例的做用域。應該返回一個字符串。
autoSelect boolean true 容許你決定是否自動選擇第一個建議。關閉它意味着若是沒有選擇任何內容(或Enter或Tab),輸入將不會清空。
afterSelect function $.noop() 選擇一個條目後的回調函數。It gets the current active item in parameter if any.
delay integer 0 在查找之間添加延遲
appendTo jQuery element null 默認狀況下,菜單將會出如今輸入元素的以後。使用這個選項來添加菜單到其餘div。若是你想使用bootstrap的dropup或者dropdown-menu-right classes,就不要使用它
fitToElement boolean false 若是你但願菜單的大小與其所連接的輸入的大小相同,置爲true
addItem JSON object false 在list的最後添加一個條目,例如「New Entry」。這可能被用到,例如當一個條目在數據集中沒有被找到的時候,彈出對話框。

示例代碼

使用靜態的內容網上資料不少,直接給source就能夠了,更加廣泛的需求是:經過aJax動態的查詢。async

ajax動態查詢

$("#search-platform").typeahead({
        source: function (query, process) {
            return $.ajax({
                url: '/domain/xxxx',
                type: 'post',
                data: {name: query},
                success: function (result) {
                    return process(result);
                },
            });
        }
});

這裏咱們只使用了一個source選項,指定一下數據源,經過上表咱們瞭解到source能夠是一個帶有兩個參數的函數,其兩個參數分別爲query和process,query是當前輸入框中所輸入的內容process是一個回調函數,它用來將咱們獲得的結果轉換爲typeahead組件能夠識別的數據。結合上面一段代碼,咱們返回的內容是經過ajax請求獲得的結果,可是這個結果通過了process進行處理。ide

ajax動態查詢,定製顯示內容

上面的需求很簡單,可是有的時候要考慮更加完善的狀況,比方說如今有一個查詢框,是用來查詢學生姓名的,考慮問題:函數

學生存在重名狀況,咱們具體想查詢的是學號爲001的叫張三的學生,但咱們不能輸入001,需求就是輸入張三,並且查詢的時候,必定是根據學號(主鍵)來查詢的,那麼咱們能夠這樣顯示:

可是如何顯示成這種形式,而且咱們如何獲取後面的學號呢?

1.首先,ajax所訪問的後臺接口就不能只返回name的字符串數組,而應該返回對象。返回一組Student對象,而且以JSON字符串形式返回。這樣前段所接受的內容就是一個JSON對象的集合

2.可是在顯示上是有問題的,它將顯示爲:

咱們能夠發現幾個問題:1.顯示格式爲JSON字符串,2.若是Student類含有其它屬性,那麼也會顯示出來,除非咱們爲了這個需求從新設計一個簡單對象。

如今考慮解決這幾個問題:

1.只保留須要顯示/使用的字段

2.顯示格式正確,不要JSON格式

3.只能根據姓名檢索

source

對於第一個問題,咱們須要對數據作預處理,即對ajax獲取的數據作處理:

success: function (result) {
                    var resultList = result.items.map(function (item) {
                        var aItem = {id: item.id, name: item.name};
                        return JSON.stringify(aItem);
                    });
                    return process(resultList);
                }

result是接口返回的JSON數據,個人數據被一個items對象所包裹,因此是result.items.map。

highlighter

前面瞭解到,highlighter是用來高亮匹配項的,這個高亮可使用咱們本身想要的風格。方法的原始實現也是高亮匹配內容,可是這裏不適用,咱們但願只顯示name:

/**
         * 使用指定的方式,高亮(指出)匹配的部分
         *
         * @param obj 數據源中返回的單個實例
         * @returns {XML|void|string|*} 數據列表中數據的顯示方式(如匹配內容高亮等)
         */
        highlighter: function (obj) {
            var item = JSON.parse(obj);
            var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
            return item.name.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
                return '<strong>' + match + '</strong>'
            });
        }

這裏反回了html文本,加粗匹配項。這樣顯示出來的內容就是隻有name的狀況。但這還不夠,你會發現當你選中了一個條目,填充到輸入框的內容仍是JSON格式。咱們還須要重寫updater方法:

updater

/**
         * 在選中數據後的操做,這裏的返回值表明了輸入框的值
         *
         * @param obj
         * @return 選中後,最終輸入框裏的值
         */
        updater: function (obj) {
            var item = JSON.parse(obj);
            return item.name;
        }

最終輸入框中咱們只讓他回填name。

這樣最終的顯示內容就符合了需求,可是當咱們提交表單進行查詢的時候,仍是沒有id這個值,這裏可能須要一個隱藏域來存放id,咱們在updater中將隱藏域的value設置爲item.id就能夠了。

 

 

 

參考資料:

[1].Bootstrap typeahead使用問題記錄及解決方案

[2].bootstrap-3-typeahead

相關文章
相關標籤/搜索