以编程方式触发 typeahead.js 结果显示
Posted
技术标签:
【中文标题】以编程方式触发 typeahead.js 结果显示【英文标题】:Programmatically triggering typeahead.js result display 【发布时间】:2013-02-13 10:26:49 【问题描述】:我在从查询字符串预填充的输入字段上使用 Twitter 的 typeahead.js (https://github.com/twitter/typeahead.js/)。加载页面后,我想以编程方式触发预输入结果的显示,而用户无需在表单字段中输入任何内容。
开箱即用,仅当用户在输入字段中手动输入内容时才会触发 typeahead.js,而我在 typeahead.js 中找不到任何可以调用来触发结果显示的方法。
任何指针将不胜感激。
谢谢!
【问题讨论】:
感谢大家的精彩回答!我通过触发输入选择了一个,因为这也强制输入在显示结果之前搜索关键字(对我的要求,我意识到这不是我的问题)。再次感谢。 *** 比切片面包好得多。 可以使用prefetch
功能
【参考方案1】:
触发输入似乎可以做到。
$(".typeahead").eq(0).val("Uni").trigger("input");
在example page 上对此进行了测试。
【讨论】:
嗨,除了在 IE 中(谁会猜到),它的效果很好。 IE 似乎只是返回一个 jQuery 对象,如下所示:shorttext.com/SuWiMi 我在 JS 中的调试能力不够好,所以如果有人有建议,我很想听听。谢谢! 换成"paste"
而不是"input"
没有"Uni"
,你能做到吗? =\
对于任何查看此内容以获取更高版本的预输入的人,您可以使用$(".typeahead").typeahead("setQuery","Uni").focus();
,因为setQuery
是设置查询值的首选 API 方法。
@Pricey:我认为 setQuery 在 0.10 中已被删除。我试过了,我得到一个错误【参考方案2】:
根据我的测试(参见fiddle),为了显示下拉菜单,需要使用focus() 方法。所以:
theVal = $('.typeahead').val();
$(".typeahead").typeahead('val', '')
$(".typeahead").focus().typeahead('val',theVal).focus();
在第 1 行,我们将 Typeahead 输入的当前值分配给变量 theVal;
在第 2 行,我们简单地重置 typeahead 的计算值;和
在第 3 行,我们将原始值放回 和焦点,这会导致建议下拉菜单显示为好像用户输入了某些内容。
我实际上需要这个来强烈鼓励用户从来自地理编码 API 调用的 Bloodhound 建议中进行选择,这样我就可以确保在提交表单之前由客户端获取坐标。
【讨论】:
【参考方案3】:$(".typeahead").typeahead('lookup').focus();
使用现有输入值触发。你当然可以提前更改值
【讨论】:
【参考方案4】:对于任何在 0.11.1 版之后使用 twitter 的 typeahead 发现这个问题的人,我是这样用一行来解决它的:
$(".typeahead-input").typeahead('val', "cookie")
.trigger("input")
.typeahead('open');
【讨论】:
【参考方案5】:从 Typeahead v0.10.1 开始,更改 typeahead 的值将触发另一个查询并打开下拉列表:
var val = $(".typeahead").typeahead('val');
$(".typeahead").typeahead('val', '');
$(".typeahead").typeahead('val', val);
【讨论】:
这是唯一对我有用的(v0.11.1),除了我必须将第一行更改为:var val = $("#original-input-id").typeahead('val');
其中#original-input-id
是我的输入文本字段的 id我添加了.typeahead
类【参考方案6】:
我使用了 twitter bootstrap typeahead,并希望在焦点上,建议列表将打开。 这里的答案不太适合我,所以我写了这个简单的指令(需要 jquery):
.directive('typeaheadFocusTrigger', function()
return
limit: 'A',
link: function(scope, element, attrs)
$(element).on('focus', function(e)
var $target = $(e.target);
var origVal = $target.eq(0).val();
$target.eq(0).val('').trigger('input')
.eq(0).val(origVal).trigger('input');
);
);
现在只要添加这个属性,它就会在焦点上触发
<input typeahead-focus-trigger typeahead="">
【讨论】:
trigger('input') 不在 IE 上所以只需将其更新为:trigger('change') 用于所有浏览。【参考方案7】:使用:Typeahead v0.10.5
不要使用:
$('.typeahead').typeahead('open');
这目前不起作用。来源:https://github.com/twitter/typeahead.js/issues/798。 作为临时修复,使用自定义 jQuery keydown 事件(在您实例化预输入之后):
var ttInstance = $('.typeahead').typeahead( config ); // Create Typeahead
ttInstance.typeahead('val', 'pancakes'); // Set an initial value
var evt = jQuery.Event('keydown');
evt.keyCode = evt.which = 40;
ttInstance.trigger(evt); // Opens the dropdown
【讨论】:
在这里给出的所有答案中,这是唯一对我有用的答案。【参考方案8】:查看源代码,似乎在typeahead
键下的元素数据中存储了一个TypeaheadView
对象。这个TypeaheadView
对象有一个内部方法_showDropdown
,它在内部绑定到焦点事件(以及其他一些事件)。
我不建议这样做,但您应该可以手动调用该内部方法:
$('#yourTypeaheadElement').data('typeahead')._showDropdown();
或者,您是否尝试过在页面加载时简单地聚焦您的 typeahead 元素(当然是在将其初始化为 typeahead 元素之后):
// after page loads and yourTypeaheadElement is initialized as a typeahead
$('#yourTypeaheadElement').focus();
【讨论】:
这似乎不适用于 typeahead*.js*。【参考方案9】:除非您故意将“typeahead”放入输入标签的类中,否则这些都不起作用。如果你觉得不需要这样做(它没有必要工作),你最好使用 typeahead.js 写入输入标签的类。它是“.tt 输入”。这是我从 Sam_Butler 抄录的示例,为新的 CSS 类重新编码。这在最新的 typeahead 0.10.5 中适用于我:
var theVal = jQuery('.tt-input').val();
jQuery(".tt-input").typeahead('val', 're')
jQuery(".tt-input").focus().typeahead('val',theVal).focus();
【讨论】:
【参考方案10】:查看了源码,发现了这种无证的方式:
var $myinput = $('#myinput');
$myinput.data('typeahead')._showDropdown()
【讨论】:
【参考方案11】:这应该适用于“旧”引导预输入插件:
$(".typeahead").eq(0).trigger("keyup");
不幸的是,还没有用 IE 测试过...... 不知道新的 typeahead 插件...
【讨论】:
【参考方案12】:这是@Sam_Butler 作品的简化版:http://jsfiddle.net/rimian/hrnf9
<button type="button" id="button">Crick</button>
<input type="text" id="text" class="typeahead">
$('#button').click(function()
$("#text").focus().typeahead('val', 'London');
);
// instantiate the bloodhound suggestion engine
var locations = new Bloodhound(
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote:
url: 'https://maps.googleapis.com/maps/api/geocode/json?address=%QUERY&components=country:GB&sensor=false®ion=uk', //add key
filter: function (locations)
return $.map(locations.results, function (location)
return
value: location.formatted_address
;
);
);
locations.initialize();
$('#text').typeahead(null,
name: 'value',
displayKey: 'value',
source: locations.ttAdapter()
);
【讨论】:
这对我很有用。我已经在文本字段中有一个值,所以我只是将它保存在一个 var 中,在 typeahead 中清空 val,然后再次设置 prev 值并打开搜索。也许是一个 hack,但工作正常。【参考方案13】:小心这个!
对于那些正在考虑手动触发 typeahead 行为(例如单击按钮)的人,我强烈建议您不要这样做。
我是为这个解决方案而来的,但我花了将近一整天的时间来解决它的问题(在我的例子中,这是一个按钮点击)。
对于那些真正想走这条黑暗道路的人,我与你分享我的丑陋代码,使其工作:
//Removes default features of typeahead
//This means that typeahead will not work like an "autocomplete", it only will be trigged when the user Click in #btnSearch button!
var txt = $("#typeahead");
//Save input events in variables (we'll need them)
eventInput = $._data(txt[0], "events").input[0];
eventBlur = $._data(txt[0], "events").blur[1];
//Remove input events
txt.unbind("blur");
txt.unbind("input");
//Set click event that triggers typeahead features manually
$("#btnSearch").click(function ()
//Clears the cache of engine for it call ajax again, without it when the term was already searched the ajax is not called!
engine.clearRemoteCache();
txt.focus(); //When we click in a button, the focus from input is lost, so we set it again to not lose the behaviors of keyboard keys (up, down, tab, etc)
txt.bind("input", eventInput); //Bind the event that we had saved
txt.trigger("input"); //Trigger input (like the answer from @epascarello)
txt.unbind("input"); //Removes it again
);
//Set event on parent of the suggestion's div, this makes the sugestion div close when user click outside it
$("body").click(function ()
if (eventBlur != undefined)
if ($(".tt-dropdown-menu:visible").length > 0)
eventBlur.handler(); //This event closes the suggestion menu
);
我做的另一件事是更改 typeahead.js 上的事件 "_checkInputValue" 的代码。我改变了这个:
areEquivalent = areQueriesEquivalent(inputValue, this.query);
到这里:
areEquivalent = false;//areQueriesEquivalent(inputValue, this.query);
我将它设置为 false 因为 typeahead 不要向服务器发送两个相同的请求。当用户在搜索按钮中单击两次时会发生这种情况(我的意思是,当他多次搜索他已经搜索过的相同文本时)。无论如何,如果您使用的是本地数据,则不需要这样做。
【讨论】:
【参考方案14】:这对我有用。
$( document ).ready(function()
$('#the-basics .typeahead').typeahead(
hint: false,
highlight: true,
minLength: 0
,
name: 'states',
displayKey: 'value',
source: substringMatcher(states)
);
//set a value to input to trigger opening
$(".typeahead").eq(0).val("a").trigger("input");
//remove value for end user
$(".typeahead").eq(0).val("");
);
请参见此处,例如:http://joshuamaynard.com/sandbox/autocomplete
【讨论】:
【参考方案15】:其他答案很有帮助,但没有解决我的问题。此解决方案不涉及自定义任何 angular-ui 代码本身,并且仅用于触发 typeahead 以在显式按钮单击时获取结果。
为此,我必须将一个文本字段覆盖在另一个(禁用的)文本字段之上,该文本字段是具有预输入功能的实际文本字段。没有人会知道另一个在那里,但它需要在那里 angular-ui 才能在正确的位置启动菜单。您不能将其设为隐藏字段,因为它将无法在正确的位置显示菜单。
下面的指令将监视typeaheadText
和typeaheadTrigger
变量以在按钮触发时填充禁用字段(通过将触发器设置为true)。该指令具有隔离范围,因此它不依赖于传入之外的任何内容。
directive('typeaheadTrigger', function()
return
require: ["ngModel"],
scope:
typeaheadText: '=',
triggerFlag: '='
,
link: function(scope, element, attr, ctrls)
scope.$watch('triggerFlag', function(value)
if (scope.triggerFlag)
ctrls[0].$setViewValue(scope.typeaheadText);
scope.typeaheadText = '';
scope.triggerFlag = false;
);
;
)
控制器为此设置了一些东西 - 对象内的触发器和文本范围变量。这演示了如何做到这一点 - 理想情况下,您会将整个内容包装在另一个指令中,以便可以在您的应用程序中使用它,同时隐藏细节。
这是笨蛋:http://plnkr.co/edit/UYjz6F5ydkMQznkZAlfx?p=preview
【讨论】:
【参考方案16】:当 tt 数据集中有 1 个项目时,我使用它手动触发选择。添加这个很有意义。
$("#mytypeahead").keyup(function (e)
var charCode = (typeof e.which === "number") ? e.which : e.keyCode;
if (charCode == 13)
if ($(this).parent().find(".tt-dataset").children().length == 1)
//This is how we are submitting a single selection on enter key
$(this).parent().find(".tt-dataset").children(0).addClass("tt-cursor");
var kde = jQuery.Event("keydown");
kde.which = 13;
$(this).trigger(kde);
);
【讨论】:
【参考方案17】:我在这里尝试了所有方法,但它不起作用,只有使用
$(".typeahead").val('hi').trigger('keyup');
$(".typeahead").val('hi').trigger('keydown');
上面的代码对我有用。不知道到底发生了什么,但两者都不使用,只有同时使用才会奏效。
【讨论】:
以上是关于以编程方式触发 typeahead.js 结果显示的主要内容,如果未能解决你的问题,请参考以下文章
Typeahead.js / Bloodhound 只显示一个结果 [重复]