typeahead.js - 匹配查询以开始结果

时间:2013-07-11 14:07:52

标签: typeahead.js

我使用Twitter typeahead.js搜索名称列表,客户希望根据名字提出建议。

是否有选项让Twitter typeahead.js与每个结果的开头匹配搜索查询,而不是字符串中的任何位置?

我可以在beginsWithQuery函数中看到_updateHint变量,但是我不知道如何将其指定为选项,或者即使这与我想要实现的内容相关。 / p>

在我的项目中调用typeahead的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网站,网站搜索的名称是自定义帖子类型“模型”的标题。我创建了一个名为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参数。

现在搜索工作完全符合预期:)

2 个答案:

答案 0 :(得分: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个左右最常用的条目,然后在remote无法提供足够建议时依赖prefetch来回填建议。

答案 1 :(得分:0)

Apt解决方案将是:

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