38

我在从查询字符串预填充的输入字段上使用 Twitter 的 typeahead.js ( https://github.com/twitter/typeahead.js/ )。加载页面后,我想以编程方式触发预输入结果的显示,而用户无需在表单字段中输入任何内容。

开箱即用,仅当用户在输入字段中手动输入内容时才会触发 typeahead.js,并且我在 typeahead.js 中找不到任何可以调用来触发结果显示的方法。

任何指针将不胜感激。

谢谢!

4

17 回答 17

51

触发输入似乎可以做到。

$(".typeahead").eq(0).val("Uni").trigger("input");

在示例页面上对此进行了测试。

于 2013-02-27T15:18:35.670 回答
15

根据我的测试(见fiddle),focus() 方法是显示下拉菜单所必需的。所以:

theVal = $('.typeahead').val();
$(".typeahead").typeahead('val', '')
$(".typeahead").focus().typeahead('val',theVal).focus();
  • 在第 1 行,我们将 Typeahead 输入的当前值分配给变量theVal
  • 在第 2 行,我们简单地重置 typeahead 的计算值;和
  • 在第 3 行,我们将原始值焦点放回原处,这导致建议下拉菜单显示为好像用户输入了某些内容一样。

我实际上需要这个来强烈鼓励用户从来自地理编码 API 调用的 Bloodhound 建议中进行选择,这样我就可以确保在提交表单之前由客户端获取坐标。

于 2014-05-13T17:46:46.240 回答
10
$(".typeahead").typeahead('lookup').focus();

使用现有输入值触发。您当然可以提前更改值

于 2013-11-05T14:35:49.130 回答
9

对于任何在 0.11.1 版本之后发现 twitter 的 typeahead 问题的人,以下是我如何用一行来解决它:

$(".typeahead-input").typeahead('val', "cookie")
                     .trigger("input")
                     .typeahead('open');
于 2015-07-17T16:04:57.407 回答
8

从 Typeahead v0.10.1 开始,更改 typeahead 的值将触发另一个查询并打开下拉列表:

var val = $(".typeahead").typeahead('val');
$(".typeahead").typeahead('val', '');
$(".typeahead").typeahead('val', val);
于 2014-03-03T08:39:45.910 回答
5

我使用了 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="">
于 2014-11-19T09:52:49.663 回答
5

使用: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
于 2015-03-11T20:31:43.890 回答
3

查看源代码,它似乎TypeaheadView在 key 下的元素数据中存储了一个对象typeahead。该TypeaheadView对象有一个内部方法 ,_showDropdown它在内部绑定到焦点事件(以及其他一些事件)。

我不建议这样做,但您应该能够手动调用该内部方法:

$('#yourTypeaheadElement').data('typeahead')._showDropdown();

或者,您是否只是尝试在页面加载时简单地聚焦您的 typeahead 元素(当然,在将其初始化为 typeahead 元素之后):

// after page loads and yourTypeaheadElement is initialized as a typeahead
$('#yourTypeaheadElement').focus();
于 2013-02-27T15:06:33.257 回答
3

除非您故意将“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();
于 2015-04-01T15:44:00.970 回答
2

我查看了源代码,发现了这种未记录的方式:

var $myinput = $('#myinput');
$myinput.data('typeahead')._showDropdown()
于 2013-02-27T15:05:45.233 回答
2

这应该与“旧”引导预输入插件一起使用:

$(".typeahead").eq(0).trigger("keyup");

不幸的是,没有用 IE 测试过......不知道新的 typeahead 插件......

于 2013-11-07T16:15:12.110 回答
2

这是@Sam_Butler 作品的简化版本:http: //jsfiddle.net/rimian/hrnf9

<button type="button" id="button">Crick</button>
<input type="text" id="text" class="typeahead">

Javascript:

$('#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&region=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()
});
于 2014-06-13T03:51:33.177 回答
1

小心这个!

对于那些正在考虑手动触发 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不会向 server 发送两个相同的请求。当用户在搜索按钮中单击两次时会发生这种情况(我的意思是,当他多次搜索他已经搜索过的相同文本时)。无论如何,如果您使用的是本地数据,则不需要这样做。

于 2014-07-11T00:07:19.903 回答
1

这对我有用。

$( 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

于 2014-09-03T00:25:31.247 回答
1

其他答案很有帮助,但没有解决我的问题。此解决方案不涉及自定义任何 angular-ui 代码本身,并且仅用于触发 typeahead 以在显式按钮单击时获取结果。

为此,我必须将一个文本字段覆盖在另一个(禁用)文本字段的顶部,该文本字段是带有预输入的实际文本字段。没有人会知道另一个在那里,但它需要在那里 angular-ui 才能在正确的位置启动菜单。您不能将其设为隐藏字段,因为它将无法在正确的位置显示菜单。

当按钮触发时(通过将触发器设置为 true) ,下面的指令将监视typeaheadTexttypeaheadTrigger变量以填充禁用字段。该指令具有隔离范围,因此它不依赖于传入之外的任何内容。

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

控制器为此设置了一些东西 - 对象内的触发器和文本范围变量。这演示了如何做到这一点 - 理想情况下,您会将整个内容包装在另一个指令中,以便可以在您的应用程序中使用它,同时隐藏细节。

这是plunk:http ://plnkr.co/edit/UYjz6F5ydkMQznkZAlfx?p=preview

于 2014-10-09T04:03:36.210 回答
0

当 tt-dataset 中有 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);                           
                    }    
                }                    
            });
于 2016-01-09T00:51:37.637 回答
0

我在这里尝试了所有方法,但它不起作用,只能使用

$(".typeahead").val('hi').trigger('keyup');
$(".typeahead").val('hi').trigger('keydown');

上面的代码对我有用。不知道到底发生了什么,但使用两者都没有起作用,只有同时使用它才起作用。

于 2018-12-19T13:50:33.073 回答