我正在尝试通过我从Elastic搜索服务器获取的搜索结果向搜索栏引入自动完成功能。起初,我对Bootstrap-typeahead js和更新的独立版本的大量示例感到困惑。现在,我有两种方法可以解决这个问题,而且两种方式都没有完全发挥作用。
第一种方法是将keyup
事件处理程序绑定到搜索栏。此处理程序在我键入时收集查询,每次键入时都会向弹性服务器发送请求(不接触数据库),并以JSON格式获取结果。它将字符串化的JSON放在localStorage
中(我试过没有字符串化,我遇到了一些问题 - 它变成了一个字符串"[object Object]"
,而不是一个数组[object Object]
,因为它正在成为其他问题。 / p>
在预先输入代码块的source
函数中,我将其解析回JSON对象,然后进行一些处理以获取建议框的产品名称列表。
示例JSON - :
[{'productName': 'FirstProduct'}, {'productName': 'FirstProd'}]
JS Code First Way - :
$(document).ready(function() {
$('#search-text').keyup(function() {
localStorage.removeItem('autocomplete_data')
$.getJSON($SCRIPT_ROOT + '/search-auto-complete', {
q: $('#search-text').val()
}, function(data, status, xhr) {
console.log("Data " + JSON.stringify(data.results));
localStorage.setItem('autocomplete_data', JSON.stringify(data.results));
});
});
$("#search-text").typeahead({
hint: true,
minLength: 3,
highlight: true
},
{
name: 'products',
displayKey: 'value',
source: function(query, process) {
products = [];
data = JSON.parse(localStorage.getItem('autocomplete_data'));
for (var index = 0; index < data.length; index++) {
for (var key in data[index]) {
products.push(data[index][key]);
}
}
console.log("product names: " + products)
process(products);
}
});
这个问题是,当我输入结果并且在输入“First”时出现两个建议行时,建议为undefined
,而不是产品名称。这几乎是一个解决方案,但我不确定这是否是正确的方法来实现我想要实现的目标(结果为我输入)。
第二种方法涉及使用先前github示例中给出的Bloodhound建议引擎。这种方法的问题是在加载DOM时生成URL(因为ready
),此时搜索栏中没有任何内容,因此$.('#search-text').val()
返回一个空字符串{ {1}}返回$('.typeahead').typeahead('val')
。我通过在HTML中放置一个虚拟undefined
来确认这一点,当我输入内容并且文本满足最小长度时,它会将此值发送到服务器。
此外,它只向服务器发送一次请求,而不是生成我输入的结果。这可能是设计上的。
JS Code Second Way - :
value="dummy"
添加下面搜索框的HTML以供参考。我还必须添加一些CSS以防止搜索框在第二种方法中变得不到宽度的一半 - 这是我在另一个Stackoverflow线程中发现的,其中解释了较新的typeahead与Bootstrap不兼容。
HTML - :
$(document).ready(function() {
var products = new Bloodhound({
datumTokenizer: function(datum) {
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: $SCRIPT_ROOT + '/search-auto-complete' + '?q=' + $('#search-text').val(),
filter: function(products) {
// Map the remote source JSON array to a JavaScript object array
return $.map(products.results, function(product) {
return {
value: product.productName
};
});
}
}
});
products.initialize();
$('#search-bar .typeahead').typeahead({
hint: true,
minLength: 5,
highlight: true
}, {
displayKey: 'value',
source: products.ttAdapter()
});
});
对任何一种方法的任何建议都将不胜感激!
答案 0 :(得分:1)
我已经设法通过第二种方法做到了。
我做的唯一改变是将url位写成如下 - :
url: $SCRIPT_ROOT + '/search-auto-complete?q=%QUERY'
这就是诀窍!建议框现在已正确填充。
道具Dave向我展示了这个例子。不得不仔细阅读,看看我错过了什么。