Twitter Typeahead.js:单击/聚焦时显示所有选项

Posted

技术标签:

【中文标题】Twitter Typeahead.js:单击/聚焦时显示所有选项【英文标题】:Twitter Typeahead.js: show all options when click/focus 【发布时间】:2013-11-16 19:43:15 【问题描述】:

我在自动完成文本输入中使用 Typeahead.js,它很棒。但是当输入获得焦点时,我需要使用所有可用选项激活下拉菜单。我见过的每个可能的解决方案都涉及使用一些值初始化输入,但我需要显示所有选项。

我怎样才能做到这一点?

【问题讨论】:

相关问题:***.com/questions/23429918. 【参考方案1】:

任何说“minLength: 0 is all you need”的答案都是不正确的。

“开箱即用”Typeahead v0.11.1 '确实需要' minLength 设置为 0,但如果您使用的是开箱即​​用的 Bloodhound 引擎,那么您需要确保设置

identify: function(obj)  return obj.team; ,

在你的寻血猎犬对象上..

您还需要一个“中间人”功能来处理您的“空查询”,这就是您告诉 Bloodhound 合作的地方。..

function nflTeamsWithDefaults(q, sync) 
  if (q === '') 
    sync(nflTeams.all()); // This is the only change needed to get 'ALL' items as the defaults
   else 
    nflTeams.search(q, sync);
  

您可以在此处查看完整示例..

var nflTeams = new Bloodhound(
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('team'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  identify: function(obj)  return obj.team; ,
  prefetch: '../data/nfl.json'
);

function nflTeamsWithDefaults(q, sync) 
  if (q === '') 
    sync(nflTeams.all()); // This is the only change needed to get 'ALL' items as the defaults
  

  else 
    nflTeams.search(q, sync);
  


$('#default-suggestions .typeahead').typeahead(
  minLength: 0,
  highlight: true
,

  name: 'nfl-teams',
  display: 'team',
  source: nflTeamsWithDefaults
);

更具体地说,您可以在以下地址看到官方 TWITTER TYPEAhead 默认建议焦点示例,从 .get() 到 .all() 的简单更改(见上文或下文)

http://twitter.github.io/typeahead.js/examples/#default-suggestions

...希望这对某人有所帮助,因为我花了一些时间才找到这些信息(通过遵循所有错误报告并尝试查找 .all() 方法找到它)...

【讨论】:

这简直太完美了。与 0.11.1 版配合得很好 当你有 Bloodhound 的“远程”选项时,不知何故这不起作用。 nflTeams 搜索运行,执行远程查询,获取数据,但它不显示为类型提示。任何线索如何解决这个问题? 我自己找到了解决方案。 Bloodhound 搜索有 3 个参数:q、sync 和 async,因此您只需为中间人功能添加 async 并在其中进行搜索。【参考方案2】:

您需要使用选项minLength: 0

注意:

有一个pull request 解决了这个问题

【讨论】:

截至今天(10/31/14),当传递 minLength: 0 时,库仍然不执行请求的行为(尽管如果您键入一些内容然后退格,这样就不再有任何输入)。然而,斯科蒂的上述解决方案有效。 minLength: 0 选项似乎部分有效。如果单击输入字段,则可以通过按键盘上的向下箭头查看所有可用结果。不过如果在焦点上这样做会很好。【参考方案3】:

我对 10.2 进行了快速修改,使“基础”示例 found here 显示在焦点上。

我更改了 mixin _onFocus(第 1459 行)FROM:

_onFocused: function onFocused() 
    this.isActivated = true;
    this.dropdown.open();
,

到:

_onFocused: function onFocused() 
    this.isActivated = true;
    var val = this.input.getInputValue(); 
    var query = Input.normalizeQuery(val);
    this.dropdown.update(query);
    this.dropdown.open();
,

这几乎不是官方的,但它完成了工作。

【讨论】:

很好,它工作正常,但你错过了var 前面的valquery【参考方案4】:

使用 0.10.4

要返回空白查询的所有结果,请在 Bloodhound.js 的第 450 行添加以下内容

     if (query == "")  return that.datums; 

要在焦点上触发匹配,在焦点上触发您输入的按键事件

     $(input_element).on("click", function () 
        ev = $.Event("keydown")
        ev.keyCode = ev.which = 40
        $(this).trigger(ev)
        return true
    );

【讨论】:

这是有效的解决方案。要使其在输入单击上工作,您需要将其与***.com/a/24665299/449009(上图)结合使用。旁注:第 450 行表示来自 SearchIndex 类的 get 方法。遗憾的是需要源黑客来获得这样的基本功能,他们正在像乌龟一样努力..【参考方案5】:

现在有一种方法可以做到这一点,而无需修改预先输入的源文件。 您必须做两件事 - 将 minlength 设置为 0 并为焦点事件添加事件处理程序: 在下面的示例中,我从 Twitter 页面 (https://twitter.github.io/typeahead.js/examples/) 上的第一个示例中复制 - 确保 typeahead.js 和 jquery-ui.js 的位置正确。

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="typeahead.js"></script>
<script src="jquery-ui.js"></script>
   <script>
   $(function()
var substringMatcher = function(strs) 
  return function findMatches(q, cb) 
    var matches, substrRegex;

    // an array that will be populated with substring matches
    matches = [];

    // regex used to determine if a string contains the substring `q`
    substrRegex = new RegExp(q, 'i');

    // iterate through the pool of strings and for any string that
    // contains the substring `q`, add it to the `matches` array
    $.each(strs, function(i, str) 
      if (substrRegex.test(str)) 
        // the typeahead jQuery plugin expects suggestions to a
        // javascript object, refer to typeahead docs for more info
        matches.push( value: str );
      
    );

    cb(matches);
  ;
;

var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
  'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
  'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
  'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
  'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
  'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
  'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
  'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
  'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];

$('.typeahead').typeahead(
  hint: true,
  highlight: true,
  minLength: 0
,

  name: 'states',
  displayKey: 'value',
  source: substringMatcher(states)
);
 $('.typeahead').on( 'focus', function() 
          if($(this).val() === '') // you can also check for minLength
              $(this).data().ttTypeahead.input.trigger('queryChanged', '');
      );
);
   </script>
    </head>
<body>
  <input class="typeahead" type="text" placeholder="States of USA">
</div>

</body>
</html>

验证这适用于 0.10.5。注意:发现这不适用于 Bloodhound 搜索引擎,因为 Bloodhound 的 queryTokenizer 需要一个字符。

【讨论】:

【参考方案6】:

现在有一种更简单的方法可以做到这一点,而无需修改源代码。可能是自从最初回答后来源已经改变,但我认为值得放在这里以防万一。

创建预输入后:

var $element = $('#myTextElement');
$element.typeahead( source: ['Billy', 'Brenda', 'Brian', 'Bobby'] );

只需将 minLength 设置为 0:

$element.data('typeahead').options.minLength = 0;

在创建预输入时minLength选项被强制为1,但你可以在创建后设置它,它可以完美地工作。

【讨论】:

这在 0.10.5 上对我不起作用。我收到以下错误:TypeError: $element.data(...) is undefined @SteveL,是的 - 看起来他们在 0.10.5 中改变了很多东西。我尝试使用新版本修改 minLength 属性,但它似乎不起作用。这是一个小提琴,您可以在其中看到我的微弱尝试:jsfiddle.net/zL9uxm45【参考方案7】:

在 typeahead v.0.11.1 中,已应用其他答案中引用的补丁。您可以通过以下选项实现此目的:

minLength: 0

适用于键盘或鼠标焦点。无需更改代码或新事件。

【讨论】:

【参考方案8】:

实现此行为的最简单方法是将 minLinegth 设置为零并设置 prefetch 属性。而不是设置本地 JSON 源,只需输入不带查询参数的搜索 url:

let baseUrl = 'some-url.com',
    url = baseUrl + '?search=%QUERY';

...

$el.typeahead(
    minLength: 0,
    highlight: true,
    prefetch: baseUrl
, 
    ...
);

【讨论】:

【参考方案9】:

另一种选择是使用 Typeahead 的非公共 API。完整的 Typeahead 对象可通过 jQuery 的 data 方法获得。

var _typeaheadElem = $('#myInput').find('.typeahead');
var _typeahead = _typeaheadElem.data('ttTypeahead');

_typeaheadElem.focus(function() 
    /* WARNING: This is hackery abusing non-public Typeahead APIs */
    if (_typeaheadElem.val() === "") 
        var input = _typeahead.input; //Reference to the TA Input class
        //Set the component's current query to something !== input.
        input.query = "Recent People";
        input._onInput("");
    
);

查看更多适用于 v0.10.2 的代码 http://pastebin.com/adWHFupF

这与 PR 719 相关联 https://github.com/twitter/typeahead.js/pull/719

【讨论】:

以上是关于Twitter Typeahead.js:单击/聚焦时显示所有选项的主要内容,如果未能解决你的问题,请参考以下文章

Twitter typeahead .js 文件未更新

Twitter Typeahead.js - 选择时删除数据

使用 Django 通过远程数据提高 Twitter 的 typeahead.js 性能

typeahead 表单,为用户提供提示或数据。自动补全typeahead.js

使用 Twitter Typeahead.js 的多个远程源

Twitter Typeahead.js 如何返回字符串中的所有匹配元素