【问题标题】:Programmatically triggering typeahead.js result display以编程方式触发 typeahead.js 结果显示
【发布时间】:2013-02-13 10:26:49
【问题描述】:

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

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

任何指针将不胜感激。

谢谢!

【问题讨论】:

  • 感谢大家的精彩回答!我通过触发输入选择了一个,因为这也强制输入在显示结果之前搜索关键字(对我的要求,我意识到这不是我的问题)。再次感谢。 Stackoverflow 比切片面包好得多。
  • 可以使用prefetch功能

标签: javascript typeahead.js


【解决方案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">
              

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

              【讨论】:

              • 这对我很有用。我已经在文本字段中有一个值,所以我只是将它保存在一个 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 才能在正确的位置启动菜单。您不能将其设为隐藏字段,因为它将无法在正确的位置显示菜单。

                  下面的指令将监视typeaheadTexttypeaheadTrigger 变量以在按钮触发时填充禁用字段(通过将触发器设置为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');
                      

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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2017-01-14
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-10-15
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多