【问题标题】:twitter bootstrap typeahead ajax exampletwitter bootstrap typeahead ajax示例
【发布时间】:2012-03-03 05:10:23
【问题描述】:

我正在尝试找到twitter bootstrap typeahead 元素的工作示例,该元素将进行 ajax 调用以填充它的下拉列表。

我有一个现有的工作 jquery 自动完成示例,它定义了 ajax url 以及如何处理回复

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { minChars:3, max:20 };
    $("#runnerquery").autocomplete('./index/runnerfilter/format/html',options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

我需要进行哪些更改才能将其转换为预先输入的示例?

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { source:'/index/runnerfilter/format/html', items:5 };
    $("#runnerquery").typeahead(options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

我将等待“Add remote sources support for typeahead”问题得到解决。

【问题讨论】:

  • 更具体地说,我想知道自动完成选项和结果处理功能如何映射到 textahead 选项?是否有一组定义的 textalert 结果处理函数可以被覆盖,或者是从底层 jquery api 继承的命名方法。
  • 您现在可以将 Stijn Van Bael 的答案标记为正确答案吗? bogert 的回答仅适用于过时的 Bootstrap 版本。

标签: jquery twitter-bootstrap jquery-autocomplete jquery-ui-autocomplete typeahead.js


【解决方案1】:

编辑:Bootstrap 3 中不再捆绑预先输入。查看:

从 Bootstrap 2.1.0 到 2.3.2,您可以这样做:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            return process(data.options);
        });
    }
});

要像这样使用 JSON 数据:

{
    "options": [
        "Option 1",
        "Option 2",
        "Option 3",
        "Option 4",
        "Option 5"
    ]
}

请注意,JSON 数据必须是正确的 mime 类型 (application/json),以便 jQuery 将其识别为 JSON。

【讨论】:

  • 与 Typeahead 分支一样,数据必须是 JSON 字符串数组,内容类型必须是 application/json。
  • 2.1可以使用不只是字符串数组的json吗?我需要给用户一个价值,并使用一个 id 来做进一步的处理。如果不拿起定制的叉子,这可能吗?
  • @Stijin 是否有任何示例说明如何在此处使用该匿名函数来处理显示选项的 id?谢谢!
  • 我想指出,使用此方法会导致为输入上的每个键击生成一个 AJAX。如果服务器返回本质上是静态的数据(即没有真正对查询做任何事情),那么这可能是非常浪费的。
  • 为什么使用 get 而不是 getJSON ?似乎更合适。
【解决方案2】:

您可以使用支持 ajax 调用的BS Typeahead fork。 然后你就可以写了:

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});

【讨论】:

  • 当我返回时,jQuery 对 POST 数据返回类型的“智能猜测”不起作用,例如,["aardvark", "apple"]。我必须在$.post 调用中明确设置dataType 参数。见jQuery.post()
  • @rfausak 或者,将Content-type 标头设置为application/json
  • 我得到了 Uncaught TypeError: Cannot call method 'toLowerCase' of undefined
  • 在您发送的链接中,我什至无法执行 source 函数。
  • 不错的答案!我会改用 GET 请求,只是为了满足 REST 标准。
【解决方案3】:

从 Bootstrap 2.1.0 开始:

HTML:

<input type='text' class='ajax-typeahead' data-link='your-json-link' />

Javascript:

$('.ajax-typeahead').typeahead({
    source: function(query, process) {
        return $.ajax({
            url: $(this)[0].$element[0].dataset.link,
            type: 'get',
            data: {query: query},
            dataType: 'json',
            success: function(json) {
                return typeof json.options == 'undefined' ? false : process(json.options);
            }
        });
    }
});

现在您可以制作统一的代码,在您的 HTML 代码中放置“json-request”链接。

【讨论】:

  • 但我会把它改成使用$(this)[0].$element.data('link')
  • this.$element.data('link')
【解决方案4】:

所有响应均指向 BootStrap 2 typeahead,它不再存在于 BootStrap 3 中。

对于其他人在这里指导寻找使用新的 post-Bootstrap Twitter typeahead.js 的 AJAX 示例,这是一个工作示例。语法有点不同:

$('#mytextquery').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  limit: 12,
  async: true,
  source: function (query, processSync, processAsync) {
    processSync(['This suggestion appears immediately', 'This one too']);
    return $.ajax({
      url: "/ajax/myfilter.php", 
      type: 'GET',
      data: {query: query},
      dataType: 'json',
      success: function (json) {
        // in this example, json is simply an array of strings
        return processAsync(json);
      }
    });
  }
});

此示例同时使用同步(对 processSync 的调用)和异步建议,因此您会看到一些选项立即出现,然后添加其他选项。您可以只使用其中一个。

有很多可绑定的事件和一些非常强大的选项,包括使用对象而不是字符串,在这种情况下,您可以使用自己的自定义 display 函数将您的项目呈现为文本。

【讨论】:

  • 谢谢。还有一个问题:使用 processAsync 我得到“TypeError:suggestions.slice 不是函数”。返回的 JSON 也需要是什么样的?这是我的最佳猜测:{ :suggestions => ["Thing 1","Thing 2","Thing 3"] }
  • 确保返回有效的 JSON 字符串。您的 AJAX 建议函数应该返回一个字符串数组,例如["Thing 1","Thing 2"],或使用自定义显示功能,根据您的需要创建一个对象数组,例如[{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]
  • 我返回 [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}],现在我想在 typeahead 下拉列表中显示两列,其中包含 id 和标签。我该怎么做?
  • 我的上帝!!!我从过去 3 天开始搜索,没有人提到这一点。到目前为止,我一直在使用同步功能进行测试。谢谢老兄!!
  • 谢谢!与 bootstrap 4.3 和 jquery 3.4 配合使用效果很好。但是,当鼠标悬停在列出的选项上时,它不会突出显示。我认为它应该是 typeahead 本身的一部分。
【解决方案5】:

我用 ajax 功能增强了原来的 typeahead Bootstrap 插件。非常容易使用:

$("#ajax-typeahead").typeahead({
     ajax: "/path/to/source"
});

这里是 github 仓库:Ajax-Typeahead

【讨论】:

  • 我看过 Gudbergur 的代码;坦率地说,我最喜欢这个。它更友好一些,并提供更多功能。干得好,保罗!我唯一建议的是在您的自述文件中提醒用户他们需要将他们的 JSON 数据解析为 JS,以便您的代码能够正确使用它。我以为你是在为我解析它,所以让我挂了一会儿。否则,很好,谢谢! :)
  • 您的服务器返回一个字符串而不是 JSON 对象。 jQuery 的 $.ajax() 用于进行调用,它负责解析。
  • 绝对正确,感谢您的捕获! :) 这个插件很好用。
  • 你好,服务器端JSON应该是什么样子的?我收到Uncaught TypeError: Cannot read property 'length' of undefined 。我正在使用json_encode($array) 并发送正确的标题('Content-Type: application/json; charset=utf-8')。 jquery 版本jQuery v1.9.1
【解决方案6】:

我对 jquery-ui.min.js 做了一些修改:

//Line 319 ORIG:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(...
// NEW:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").addClass("typeahead").addClass("dropdown-menu").appendTo(d(...

// Line 328 ORIG:
this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr...
// NEW:this.element.attr....

// Line 329 ORIG:
this.active=a.eq(0).children("a")
this.active.children("a")
// NEW:
this.active=a.eq(0).addClass("active").children("a")
this.active.removeClass("active").children("a")`

并添加以下css

.dropdown-menu {
    max-width: 920px;
}
.ui-menu-item {
    cursor: pointer;        
}

完美运行。

【讨论】:

  • 您使用的是哪个版本的 jquery ui min?
  • 如果您在 jQuery 1.7.1 和 jQuery UI 1.8.16 中需要这个,那么我已经创建了一个基于上述修复的 GIST,它显示了更改 jQuery UI 文件的位置。 gist.github.com/1884819 - 行注释为 //modified
  • 这是一个很老的问题/答案,但我只想说,更改 3rd 方组件代码总是一种不好的做法。每次升级时,您都必须重新访问所有更改。在这种特殊情况下,可以继承 jQuery 小部件,这是一种更安全的自定义方式。所以基本上,创建你自己的小部件,继承核心部件(在这种情况下是自动完成)并释放你的想象力! :)
【解决方案7】:

我正在使用这种方法

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
},
    {
    name: 'options',
    displayKey: 'value',
    source: function (query, process) {
        return $.get('/weather/searchCity/?q=%QUERY', { query: query }, function (data) {
            var matches = [];
            $.each(data, function(i, str) {
                matches.push({ value: str });
            });
            return process(matches);

        },'json');
    }
});

【讨论】:

  • 如果您可以在答案中添加一些解释,那就太好了。例如,与现有答案中提供的解决方案相比,您的解决方案有什么不同?
【解决方案8】:

可以使用 Bootstrap 拨打电话。当前版本没有任何源更新问题 Trouble updating Bootstrap's typeahead data-source with post response ,即更新后的bootstrap源可以再次修改。

请参考以下示例:

jQuery('#help').typeahead({
    source : function(query, process) {
        jQuery.ajax({
            url : "urltobefetched",
            type : 'GET',
            data : {
                "query" : query
            },
            dataType : 'json',
            success : function(json) {
                process(json);
            }
        });
    },
    minLength : 1,
});

【讨论】:

    【解决方案9】:

    致那些寻找已接受答案的咖啡脚本版本的人:

    $(".typeahead").typeahead source: (query, process) ->
      $.get "/typeahead",
        query: query
      , (data) ->
        process data.options
    

    【讨论】:

      【解决方案10】:

      我浏览了这篇文章,一切都不想正常工作,最终从几个答案中拼凑起来,所以我有一个 100% 工作演示并将其粘贴到此处以供参考 - 将其粘贴到 php 文件中并确保包含在正确的位置。

      <?php if (isset($_GET['typeahead'])){
          die(json_encode(array('options' => array('like','spike','dike','ikelalcdass'))));
      }
      ?>
      <link href="bootstrap.css" rel="stylesheet">
      <input type="text" class='typeahead'>
      <script src="jquery-1.10.2.js"></script>
      <script src="bootstrap.min.js"></script>
      <script>
      $('.typeahead').typeahead({
          source: function (query, process) {
              return $.get('index.php?typeahead', { query: query }, function (data) {
                  return process(JSON.parse(data).options);
              });
          }
      });
      </script>
      

      【讨论】:

        【解决方案11】:

        如果您的服务未返回正确的应用程序/json 内容类型标头,请尝试此操作:

        $('.typeahead').typeahead({
            source: function (query, process) {
                return $.get('/typeahead', { query: query }, function (data) {
                    var json = JSON.parse(data); // string to json
                    return process(json.options);
                });
            }
        });
        

        【讨论】:

          【解决方案12】:

          更新:我使用this fork 修改了我的代码

          我也没有使用 $.each,而是按照 Tomislav Markovski 的建议改为了 $.map

          $('#manufacturer').typeahead({
              source: function(typeahead, query){
                  $.ajax({
                      url: window.location.origin+"/bows/get_manufacturers.json",
                      type: "POST",
                      data: "",
                      dataType: "JSON",
                      async: false,
                      success: function(results){
                          var manufacturers = new Array;
                          $.map(results.data.manufacturers, function(data, item){
                              var group;
                              group = {
                                  manufacturer_id: data.Manufacturer.id,
                                  manufacturer: data.Manufacturer.manufacturer
                              };
                              manufacturers.push(group);
                          });
                          typeahead.process(manufacturers);
                      }
                  });
              },
              property: 'name',
              items:11,
              onselect: function (obj) {
          
              }
          });
          

          但是我遇到了一些问题

          未捕获的类型错误:无法调用未定义的方法“toLowerCase”

          正如您在较新的帖子中看到的那样,我正在尝试找出 here

          希望此更新对您有所帮助...

          【讨论】:

          • 与 OP 无关:我会使用 Array.map 而不是 $.each 并将整个 success 回调函数的内容替换为 var manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } });
          • 谢谢@TomislavMarkovski 我按照你的建议修改了我的代码。
          • 对于最新版本,使用“display”而不是“property”
          【解决方案13】:

          我没有适合你的工作示例,也没有非常干净的解决方案,但让我告诉你我发现了什么。

          如果您查看 TypeAhead 的 javascript 代码,它看起来像这样:

          items = $.grep(this.source, function (item) {
              if (that.matcher(item)) return item
            })
          

          此代码使用 jQuery“grep”方法来匹配源数组中的元素。我没有看到任何可以挂接到 AJAX 调用的地方,因此没有“干净”的解决方案。

          但是,您可以使用 grep 方法在 jQuery 中的工作方式来实现这一点,这是一种有点老套的方法。 grep 的第一个参数是源数组,第二个参数是用于匹配源数组的函数(注意 Bootstrap 调用了您在初始化时提供的“匹配器”)。您可以做的是将源设置为一个虚拟的单元素数组,并将匹配器定义为一个带有 AJAX 调用的函数。这样,它只会运行一次 AJAX 调用(因为您的源数组中只有一个元素)。

          这个解决方案不仅是 hacky,而且会受到性能问题的影响,因为 TypeAhead 代码被设计为在每次按键时进行查找(AJAX 调用实际上应该只在每几次按键或一定量的空闲时间后发生)。我的建议是尝试一下,但要么坚持使用不同的自动完成库,要么仅在遇到任何问题时将其用于非 AJAX 情况。

          【讨论】:

            【解决方案14】:

            使用 ajax 时,如果无法正确显示结果,请尝试使用 $.getJSON() 而不是 $.get()

            就我而言,当我使用$.get() 时,我只得到了每个结果的第一个字符,尽管我使用了json_encode() 服务器端。

            【讨论】:

              【解决方案15】:

              我使用$().one() 为了解决这个问题; 页面加载后,我将 ajax 发送到服务器并等待完成。 然后将结果传递给函数。$().one() 很重要。因为强制 typehead.js 附加到输入一次。 抱歉写得不好。

              (($) => {
                  
                  var substringMatcher = function(strs) {
                      return function findMatches(q, cb) {
                        var matches, substringRegex;
                        // 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)) {
                            matches.push(str);
                          }
                        });
                        cb(matches);
                      };
                    };
                    
                    var states = [];
                    $.ajax({
                        url: 'https://baconipsum.com/api/?type=meat-and-filler',
                        type: 'get'
                    }).done(function(data) {
                      $('.typeahead').one().typeahead({
                          hint: true,
                          highlight: true,
                          minLength: 1
                        },
                        {
                          name: 'states',
                          source: substringMatcher(data)
                        });
                    })
                    
              
              })(jQuery);
              .tt-query, /* UPDATE: newer versions use tt-input instead of tt-query */
              .tt-hint {
                  width: 396px;
                  height: 30px;
                  padding: 8px 12px;
                  font-size: 24px;
                  line-height: 30px;
                  border: 2px solid #ccc;
                  border-radius: 8px;
                  outline: none;
              }
              
              .tt-query { /* UPDATE: newer versions use tt-input instead of tt-query */
                  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
              }
              
              .tt-hint {
                  color: #999;
              }
              
              .tt-menu { /* UPDATE: newer versions use tt-menu instead of tt-dropdown-menu */
                  width: 422px;
                  margin-top: 12px;
                  padding: 8px 0;
                  background-color: #fff;
                  border: 1px solid #ccc;
                  border: 1px solid rgba(0, 0, 0, 0.2);
                  border-radius: 8px;
                  box-shadow: 0 5px 10px rgba(0,0,0,.2);
              }
              
              .tt-suggestion {
                  padding: 3px 20px;
                  font-size: 18px;
                  line-height: 24px;
                  cursor: pointer;
              }
              
              .tt-suggestion:hover {
                  color: #f0f0f0;
                  background-color: #0097cf;
              }
              
              .tt-suggestion p {
                  margin: 0;
              }
              <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
              <script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
              
              <input class="typeahead" type="text" placeholder="where ?">

              【讨论】:

                【解决方案16】:
                 $('#runnerquery').typeahead({
                        source: function (query, result) {
                            $.ajax({
                                url: "db.php",
                                data: 'query=' + query,            
                                dataType: "json",
                                type: "POST",
                                success: function (data) {
                                    result($.map(data, function (item) {
                                        return item;
                                    }));
                                }
                            });
                        },
                        updater: function (item) {
                        //selectedState = map[item].stateCode;
                
                       // Here u can obtain the selected suggestion from the list
                
                
                        alert(item);
                            }
                
                    }); 
                
                 //Db.php file
                <?php       
                $keyword = strval($_POST['query']);
                $search_param = "{$keyword}%";
                $conn =new mysqli('localhost', 'root', '' , 'TableName');
                
                $sql = $conn->prepare("SELECT * FROM TableName WHERE name LIKE ?");
                $sql->bind_param("s",$search_param);            
                $sql->execute();
                $result = $sql->get_result();
                if ($result->num_rows > 0) {
                    while($row = $result->fetch_assoc()) {
                    $Resut[] = $row["name"];
                    }
                    echo json_encode($Result);
                }
                $conn->close();
                

                ?>

                【讨论】:

                  猜你喜欢
                  • 2014-05-23
                  • 2013-07-20
                  • 1970-01-01
                  • 2013-01-31
                  • 1970-01-01
                  • 2015-03-22
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-04-03
                  相关资源
                  最近更新 更多