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

30

我在一个自动完成的文本输入框中使用了Typeahead.js技术,这个技术很不错。但是当输入框获得焦点时,我需要激活下拉菜单并显示所有可选项。我看到的每一个可能的解决方案都涉及使用某些值初始化输入框,但我需要展示所有的选项。

我该如何实现这一目标?


相关问题:https://dev59.com/oGAg5IYBdhLWcg3wlLuh. - Sergey Vyacheslavovich Brunov
9个回答

28
任何回答说“minLength: 0就足够了”都是不正确的。
“Out Of The Box” Typeahead v0.11.1确实需要将minLength设置为0,但是如果您正在使用开箱即用的Bloodhound引擎,则还需要确保设置。
identify: function(obj) { return obj.team; },

在你的Bloodhound对象上,你需要一个“中间人”函数来处理“空查询”,这里你将告诉Bloodhound合作。请注意保留HTML标签。
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()即可(请参见上面或下面的内容),请保留HTML标签。

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

我希望这能对某些人有所帮助,因为我花了一些时间才找到这个信息(通过跟踪所有的错误报告和尝试使用 .all() 方法来找到它)...


这真是太完美了。与版本0.11.1非常兼容。 - Johny Bravo
当你为Bloodhound设置“remote”选项时,某种原因导致它无法正常工作。nflTeams搜索运行,远程查询被执行,数据被获取,但它不会出现为类型提示。有什么线索可以解决这个问题吗? - fperet
1
我已经自己找到了解决方案。Bloodhound搜索有3个参数:q、sync和async,所以您只需要为中间人函数添加async,并在其中进行搜索即可。 - fperet

14
你需要使用选项minLength: 0 注意: 有一个拉请求解决了这个问题。

截至今天(10/31/14),当传递minLength: 0时,该库仍未执行所请求的行为(尽管如果您键入某些内容,然后退格,以便不再有任何输入,则会执行)。 Scottie上面的解决方案有效。 - roberttdev
2
minLength: 0选项似乎部分起作用。如果您点击输入字段,则可以通过按下键盘上的向下箭头来查看所有可用结果。不过,如果在焦点上执行此操作会更好。 - BraMKJ

11

我对10.2进行了快速修改,使得“the basics”示例(在此处找到)在焦点上显示。

我将混合方法_onFocus(第1459行)改为:

_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();
},

虽然并不正式,但它完成了任务。


不错,它正在工作,但是你忘了在“val”和“query”前面加上“var”。 - yvesonline

3
现在有一种方法可以在不修改typeahead源文件的情况下完成此操作。您需要做两件事——将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期望一个字符。


3

使用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
    });

这是有效的解决方案。要使其在输入点击上工作,您需要将其与https://dev59.com/YmIj5IYBdhLWcg3w4Izt#24665299(上面)结合使用。旁注:第450行表示从SearchIndex类中获取方法。可惜需要进行源代码修改才能获得这样基本的功能,他们正在像乌龟一样努力解决。 - stawek

2

现在有一种更简单的方法来完成这项工作,无需修改源代码。可能自原始回答以来源代码已经发生了变化,但我认为值得在此提出。

创建typeahead后:

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

只需将minLength设置为0:

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

当创建typeahead时,minLength选项被强制设为1,但您可以在创建后设置它,并且它完美地工作。


1
这在0.10.5上对我不起作用。我得到了以下错误:TypeError:$element.data(...)未定义 - Steve L
@SteveL,是的-看起来他们在0.10.5中改变了很多东西。我尝试使用新版本修改minLength属性,但似乎不起作用。这里有一个fiddle,您可以在其中看到我的微弱尝试:http://jsfiddle.net/zL9uxm45/ - Robert

1
我实现这种行为的最简单方法是将minLength设置为零并设置prefetch属性。不要设置本地JSON源,只需使用搜索URL而不带查询参数即可。
let baseUrl = 'some-url.com',
    url = baseUrl + '?search=%QUERY';

...

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

1
在typeahead v.0.11.1中,其他答案中提到的补丁已经被应用。您可以通过使用以下选项来实现此目标: minLength: 0 适用于键盘或鼠标聚焦。无需更改代码或添加新事件。

0

另一个选择是使用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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接