2013-07-11 123 views
2

我正在使用Twitter typeahead.js搜索名稱列表,並且客戶端需要基於名字的建議。typeahead.js - 匹配查詢結果的開始

是否有一個選項讓Twitter typeahead.js匹配搜索查詢,並且每個結果的開始位置,而不是字符串中的任何位置?

我可以在_updateHint函數中看到一個beginsWithQuery變量,但是我不知道如何將它指定爲選項,或者即使這與我試圖實現的內容有關。

這是在我的項目叫預輸入jQuery的功能是:

$('input[name="s"]') 
    .typeahead({ 
     name: 'search', 
     remote: wp_typeahead.ajaxurl + '?action=ajax_search&fn=get_ajax_search&terms=%QUERY', 
     template: [ 
     '<p><a href="{{url}}">{{value}}</a></p>', 
    ].join(''), 
     engine: Hogan 
    }) 
); 

我可以看到從ajax_search響應的格式爲

[ 
    { "tokens" : [ "First","Last" ], 
    "url" : "http://url/for/first-last/", 
    "value" : "First Last" }, 
] 

,所以我需要弄清楚如何過濾此JSON以僅包含token[0]與搜索查詢匹配的數據。

編輯:關於我不得不添加的附加註釋來執行prefetch解決方案的工作,如下面的@ jharding's anwser。

這是一個WordPress網站,網站搜索的名稱是「model」的自定義帖子類型的標題。我創建了一個名爲list-all-models.php的文件,它以所需的數據格式輸出模型名稱的數組。

<?php 
define('WP_USE_THEMES', false); 
require('../../../../wp-load.php'); // depends on where this file is 

$args = array (
    'post_type' => 'model', 
    'orderby' => 'title',   
    'order' => 'asc', 
    'posts_per_page' => -1 
); 

$models = get_posts($args); 

$model_names = array(); 

foreach ($models as $i => $model) { 
    $model_names[$i]['value'] = $model->post_title; 
    $model_names[$i]['url']  = $model->guid; 
    $model_names[$i]['tokens'] = explode(' ', $model->post_title); 
} 

header("Content-type: application/json"); 
die(json_encode($model_names)); 
?> 

然後我使用此文件的URL作爲prefetch選項中的url參數。

現在搜索所以第一份工作完全按預期:)

+0

你使用遠程數據源? – Tommi

+0

@Tommi,是的。我剛剛添加了上面的相關代碼。我想我需要使用一個過濾器來將響應數據轉換爲一個基準數組,這些數據只是每個值的第一個字。但我不知道該怎麼做:( – Astrotim

+0

我建議你在服務器端做這樣的過濾。優點:客戶端瀏覽器不會執行可以掛起它的繁重操作;通過ajax =>更快的數據發送速度更快響應;你完全不需要用typeahead.js來找到方法(我快速查看了代碼,並沒有找到任何改變默認過濾的方法)如果你真的想堅持客戶端解決方案,你需要綁定你輸入的'keydown'事件,過濾你預先加載的數組,並將過濾後的結果綁定爲'local'。雖然我不確定這種typeahead設計用於這種方式。 – Tommi

回答

1

,typeahead.js沒有做任何形式的對remote返回的數據過濾的。預計由remote返回的數據已經包含給定查詢的有效建議。

聽起來像使用prefetch如果您期望typeahead.js處理查詢的匹配建議,並且由於您有〜700個條目,您應該會看到非常穩定的性能。如果你選擇走這條路,你會想要做這樣的事情:

$('input[name="s"]').typeahead({ 
    name: 'search', 
    prefetch: { 
    url: '/path/to/json/file/that/returns/all/entries', 
    filter: removeLastNameFromTokens 
    }, 
    template: '<p><a href="{{url}}">{{value}}</a></p>', 
    engine: Hogan 
}); 

function removeLastNameFromTokens(data) { 
    var datum, firstName; 

    for (var i = 0; i < data.length; i++) { 
    datum = data[i]; 
    datum.tokens.pop(); // assumes tokens looks like [First, Last] 
    } 

    return data; 
} 

假設/path/to/json/file/that/returns/all/entries指向包含基準數組的JSON文件,removeLastNameFromTokens將遍歷每個數據並刪除最後一個名字來自tokens,只留下第一個名字。這應該導致你正在尋找的功能。

另一個好的策略是使用prefetchremote的組合。您可以在prefetch數據中包含100個左右最受歡迎的條目,然後在prefetch無法產生足夠的建議時依靠remote來回填建議。

+0

該網站有大約700個條目,其中搜索正在看,所以我不確定這對我來說是一個實際的解決方案,除非我可以找出如何以編程方式添加標記 – Astrotim

+0

您可能想使用prefetch選項進行研究,然後可以使用過濾器把條目轉換成我建議的格式無論如何,如果不分叉typeahead.js,就無法實現您所要求的功能。 – jharding

+0

任何指針如何將'prefetch'選項合併到上面的函數中(我只是添加了一些代碼)?文檔狀態我需要定義一個指向基準JSON文件的URL,但是條目列表只是數據庫中所有文章的名稱。 – Astrotim

0

公寓的解決辦法是:

matcher: function (item) { 
         if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) == 0) { 
          return true; 
         } 
相關問題