Twitter引导typeahead ajax示例

我试图找到Twitter引导输入元素的工作示例,该元素将进行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];
}
);
..

我需要改变什么来转换这到typeahead的例子?

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

我将等待'为提前输入添加远程源支持'问题得到解决。

325463 次浏览

我对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;
}

完美的工作。

我没有一个可行的例子,也没有一个非常清晰的解决方案,但让我告诉你我的发现。

如果你看一下TypeAhead的javascript代码,它是这样的:

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

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

但是,有一种有点笨拙的方法可以做到这一点,那就是利用jQuery中的grep方法的工作方式。grep的第一个参数是源数组,第二个参数是用于匹配源数组的函数(注意Bootstrap在初始化时调用您提供的“matcher”)。您可以做的是将源设置为一个虚拟的单元素数组,并将匹配器定义为一个包含AJAX调用的函数。这样,它将只运行AJAX调用一次(因为源数组中只有一个元素)。

这种解决方案不仅很棘手,而且还会出现性能问题,因为TypeAhead代码被设计为对每一次按键都进行查找(AJAX调用实际上应该只在每几次按键或在一定的空闲时间之后发生)。我的建议是尝试一下,但是坚持使用不同的自动补全库,或者如果遇到任何问题,只在非ajax的情况下使用它。

你可以使用支持ajax调用的输入前叉。 然后你就可以写:

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

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

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

下面是github repo: Ajax-Typeahead

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

也不是使用$。每一个我都换成了$。由托米斯拉夫·马可夫斯基推荐的地图

$('#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) {


}
});

然而,我遇到了一些问题

无法调用undefined的方法“toLowerCase”

正如你可以在一个更新的帖子上看到的,我正在试图找出在这里

希望这个更新对你有任何帮助…

编辑:typeahead不再捆绑在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。

从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”链接。

可以使用Bootstrap进行调用。当前版本没有任何源代码更新问题 无法更新Bootstrap's typeahead数据源与后响应 也就是说,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,
});

当使用ajax,尝试$.getJSON()而不是$.get(),如果你有问题的正确显示结果。

在我的情况下,当我使用$.get()时,我只得到每个结果的第一个字符,尽管我使用json_encode()服务器端。

对于那些正在寻找公认答案的咖啡脚本版本的人:

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

我浏览了这篇文章,一切都不想正常工作,最终从几个答案拼凑在一起,所以我有一个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>

我正在用这个方法

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

所有的响应都引用BootStrap 2提前输入,这在BootStrap 3中不再存在。

对于在这里寻找使用新的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)和异步建议,所以你会看到一些选项立即出现,然后添加其他选项。你可以只用其中一个。

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

如果你的服务没有返回正确的application/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);
});
}
});
 $('#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();

? >

我使用$().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 ?">