JQuery auto complete from XML
I'm playing around with jquery ui autocomplete. And have a question about how to query the XML data. I have an XML file with a list of locations, similar to:
<geoname>
<name_en>The Tower of London</name_en>
<name_fr>Example text</name_fr>
<lat>51.5082349601834</lat>
<lng>-0.0763034820556641</lng>
<geona开发者_如何学JAVAmeId>6286786</geonameId>
<countryCode>GB</countryCode>
<countryName>United Kingdom</countryName>
<fcl>S</fcl>
<fcode>CSTL</fcode>
<web>http://www.exmaple.com</web>
</geoname>
And my jQuery is:
jQuery(document).ready(function() {
lang = 'en';
$.ajax({
url: "places.xml",
dataType: "xml",
success: function( xmlResponse ) {
var data = $( "countryCode", xmlResponse ).map(function() {
return {
value: $( "name", this ).text(),
id: $( "geonameId", this ).text(),
countryName: $( "countryName", this ).text(),
link: $( "web", this ).text(),
code: $( "countryCode", this ).text()
};
}).get();
$( "#results" ).autocomplete({
source: data,
minLength: 0,
select: function( event, ui ) {
$('#foo').html('');
$('#foo').html(ui.item.code).slideDown();
}
});
}
});
});
What I'm having trouble with is that I want to specify a variable that says only search name_en when I've set it to EN, and in other cases only search for name_fr when set to FR. I don't want name_fr results to come back when I've set the language to EN. Thanks in advance.
First, I'll post the code:
HTML
<select id="lang">
<option value="en">EN</option>
<option value="fr">FR</option>
</select>
<input type="text" id="results" />
<span id="foo" />
XML
<list>
<geoname>
<name_en>The Tower of London</name_en>
<name_fr>Example text</name_fr>
<lat>51.5082349601834</lat>
<lng>-0.0763034820556641</lng>
<geonameId>6286786</geonameId>
<countryCode>GB</countryCode>
<countryName>United Kingdom</countryName>
<fcl>S</fcl>
<fcode>CSTL</fcode>
<web>http://www.exmaple.com</web>
</geoname>
<geoname>
<name_en>En name</name_en>
<name_fr>Fr name</name_fr>
<lat>51.5082349601834</lat>
<lng>-0.0763034820556641</lng>
<geonameId>6286786</geonameId>
<countryCode>GB2</countryCode>
<countryName>United Kingdom</countryName>
<fcl>S</fcl>
<fcode>CSTL</fcode>
<web>http://www.exmaple.com</web>
</geoname>
</list>
JS
jQuery(document).ready(function() {
var lang = "en";
$("#lang").bind("change", function() {
lang = this.value;
});
$.ajax({
url: "/echo/xml/",
dataType: "xml",
success: function( xmlResponse ) {
var data = $("geoname", xmlResponse ).map(function() {
return {
value: "",
name_en: $( "name_en", this ).text(),
name_fr: $("name_fr", this).text(),
id: $( "geonameId", this ).text(),
countryName: $( "countryName", this ).text(),
link: $( "web", this ).text(),
code: $( "countryCode", this ).text()
};
}).get();
$( "#results" ).autocomplete({
source: function(req, add) {
var source = [];
for (var i = 0; i < data.length; i++)
{
if (lang == "en")
{
data[i].value = data[i].name_en;
}
else if (lang == "fr")
{
data[i].value = data[i].name_fr;
}
if (data[i].value.substr(0, req.term.length).toLowerCase() == req.term.toLowerCase())
{
source.push(data[i]);
}
}
add(source);
},
minLength: 0,
select: function( event, ui ) {
$('#foo').html('');
$('#foo').html(ui.item.code).slideDown();
}
});
}
});
});
And here is a JSFiddle solution I tested
http://jsfiddle.net/pinusnegra/KFHnd/
It's a little messy, but you can make it better if you want. I tell you how it works:
First, you receive a list of 'geoname' nodes I think, not only one:
var data = $("geoname", xmlResponse ).map(function() {
return {
value: "",
name_en: $( "name_en", this ).text(),
name_fr: $("name_fr", this).text(),
id: $( "geonameId", this ).text(),
countryName: $( "countryName", this ).text(),
link: $( "web", this ).text(),
code: $( "countryCode", this ).text()
};
}).get();
You get the name_en and name_fr value, and you set the 'value' to an empty string (the 'value' will be the jQuery autocomplete text).
In jQuery autocomplete, you can set a function to the source, which has a 'req' object, and an 'add' callback.
The 'req' object contains a 'term' property, which is the actual textbox input. The 'add' callback adds a list (an array) of the matched items.
So you initialize a 'source' array:
source: function(req, add) {
var source = [];
then you iterate over the 'data' array, and based on the current 'lang', setup the 'value' property with the actual 'name_en' or 'name_fr'.
After this, you can test on the 'object.value', if it's match the requirements:
if (data[i].value.substr(0, req.term.length).toLowerCase() == req.term.toLowerCase())
{
source.push(data[i]);
}
if so, then push into the 'source' array.
and... add(source); 'returns' the actual list.
Notice that the source function of the autocomplete object will be called everytime when a new autocomplete search occurs, so you return the right collection of items everytime.
Of course, you can make a more sophisticated and optimized solution if this one meets your requirements.
cheers, negra
精彩评论