我正在尝试加载xml文件并激活自动完成(jQuery UI),以便将xml中的数据显示到输入框中,同时用户开始在输入字段中输入内容。
目前,我的脚本使用source: data,
,其中数据是通过.map函数jquery加载的xml数组。正在通过xml的value
字段搜索用户输入,但我现在需要通过keywords
字段进行搜索。这是因为关键字在我的要求中更有效,其中单个值可以包含两个或三个关键字。
我在整个晚上搜索google和stackoverflow并在昨天午夜时间进行搜索,并在[stackoverflow]上找到了一个页面,并尝试使用该页面上给出的代码。
代码运行得很好,但我无法在自动完成中查看某些元素。数据加载正常,并显示数据数组的任何被调用索引的正确值:chrome控制台中的(console.log(data[1].value);
= sparrow
。 (根据我的xml)
但在搜索功能checkSearchWordsMatchKeywords(request.term, keywords))
之后,[k]的值发生了变化,它只返回一些结果,而不是全部。
首先我认为它没有返回第一个元素,所以我将其复制并粘贴到开头,将其复制为[0] ..以进行测试。但这似乎也不起作用,所以我猜它没有显示那组特定的关键词。
我不打算按原样使用这个脚本,而是我在这里发布有关如何在自动完成中搜索关键字的信息。如果此功能不正确,那么请有人提供不同的功能,或为此建议不同的自动完成脚本/插件吗?我打算只为此使用jQuery。
以下代码仅返回“Parrot”,“Crow”,“Pidgeon”,但在输入字段中输入“t”时不返回“Sparrow”。根据关键字,它也应该返回“Sparrow”,但它不会。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item>
<id>0</id>
<value>NoValue</value>
<url>#noValue</url>
<keywords>ewo;reeFour;veSix</keywords>
</item>
<item>
<id>1</id>
<value>Sparrow</value>
<url>gallery/birds_1.html</url>
<keywords>OneTwo;ThreeFour;FiveSix</keywords>
</item>
<item>
<id>2</id>
<value>Parrot</value>
<url>gallery/birds_2.html</url>
<keywords>SevenEigh;Nineen;tElevenwelve</keywords>
</item>
<item>
<id>3</id>
<value>Crow</value>
<url>gallery/birds_3.html</url>
<keywords>ThirteenFourteen;FifteenSixteen;SeventeenEighteen</keywords>
</item>
<item>
<id>4</id>
<value>Dove</value>
<url>gallery/Birds_4.html</url>
<keywords>Nineeenweny;wenyOnewenywo;wenyhreewenyFour</keywords>
</item>
<item>
<id>5</id>
<value>Pidgeon</value>
<url>gallery/birds_5.html</url>
<keywords>TwentyFiveTwentySix;TwentySevenTwentyEight;TwentyNineThirty</keywords>
</item>
</items>
/* get xml file using ajax */
$.ajax({
url: "birds_search.xml",
dataType: "xml",
success: function(xmlResponse) {
/* parse response */
var data = $("item", xmlResponse).map(function() {
return {
id: $("id", this).text(),
value: $("value", this).text(),
url: $("url", this).text(),
comma_keywords: $("keywords", this).text(),
//can add "../" to the url via label tag: label: "../" + url; ... and then in SELECT below, : ui.item.label. (for products directory.xml)
};
}).get();
console.log(data[1].value);
/* bind the results to autocomplete */
$("input#autocomplete_search").autocomplete({
source: function(request, response) {
var matched = [];
var k;
// Search "request.term" through all links keywords
for (k = 0; k < data.length; k++) {
var keywords = data[k].comma_keywords.split(';');
//console.log(k);
if (checkSearchWordsMatchKeywords(request.term, keywords)) {
matched.push(data[k]);
console.log(k);
}
}
// display the filtered results
response(matched);
},
//minLength: 2,
select: function (event, ui) {
window.location = ui.item.url;
}
});
}
});
function checkSearchWordsMatchKeywords(searchString, keywords)
{
var searchWords = searchString.toLowerCase().split(' '); // Lowercase the search words & break up the search into separate words
var numOfSearchWords = searchWords.length; // Count number of search words
var numOfKeywords = keywords.length; // Count the number of keywords
var matches = []; // Will contain the keywords that matched the search words
// For each search word look up the keywords array to see if the search word partially matches the keyword
for (var i = 0; i < numOfSearchWords; i++)
{
// For each keyword
for (var j = 0; j < numOfKeywords; j++)
{
// Check search word is part of a keyword
if (keywords[j].indexOf(searchWords[i]) != -1)
{
// Found match, store match, then look for next search word
matches.push(keywords[j]);
break;
}
}
}
// Count the number of matches, and if it equals the number of search words then the search words match the keywords
if (matches.length == numOfSearchWords)
{
return true;
}
return false;
}
感谢您的帮助。
答案 0 :(得分:0)
嗯,我很晚才回答我自己的问题......但这就是我最终设法实现它的方式。我只在这里复制/粘贴代码,因为它在我的js文件中,因此不会发生错误。在我的问题中,我举了一个birds.xml
的例子,现在我的情况是products.xml
......
fileStatus
变量是真还是假,具体取决于xml文件的位置....我在ajax请求中设置了检查文件的位置(不包含在此代码中)。你可以根据自己的意愿改变它,因为它是可选的。其余代码应该适用于自动完成....或者您可以更改任何不符合您要求的代码。 :d
$("input#q").autocomplete({
source: function products(request, response) { // Function PRODUCTS()
function hasMatch(s) {
//console.log(s);
//console.log(request.term.toLowerCase());
return s.toLowerCase().indexOf(request.term.toLowerCase())!==-1;
}
var i, l, obj, matches = [];
//console.log(data_global);
if (request.term==="") {
response([]);
return;
}
for (i = 0; i < data.length; i++) {
obj = data[i];
//var truefalseVar;
//console.log(obj.value);
function truefalse(){
for(j=0;j<obj.gen_name.length;j++)
{ if( hasMatch(obj.gen_name[j]) )
return true;
//else truefalseVar = false;
// console.log(obj.gen_name[j])
}
return false;
}
if (hasMatch(obj.value) || truefalse() ) {
matches.push(obj);
}
}
response(matches);
},
/* END OF Function PRODUCTS() */
//minLength: 2,
focus: function (event, ui) {
$(event.target).val(ui.item.gen_name);
event.preventDefault();
return false;
},
select: function (event, ui) {
if(fileStatus){
var prouctsURL = 'products/' + ui.item.url;
}
else var prouctsURL = ui.item.url;
window.location = prouctsURL;
}
});