Jquery Autocomplete - combine data sources - primary and fallback
I searched the forums but didn't find any answers to this question.
I am using jquery autocomplete to populate form fields.
I am currently using local data from an XML file (code part one below). This works great for the answers I need for local queries, but I would like to have a fallback data source (JSON geoname - see code part two below) if the local XML does not contain the right query result.
I tried and failed to merge the two data sources, so for the sake of simplicity, I'm posting them individually here.
They both work independently - but how to merge them into one results field? Also, the XML data should be the primary choice.
CODE PART ONE
Code for the XML local source
$(document).ready(function() {
var myArr = [];
$.ajax({
type: "GET",
url: "airports.xml",
dataType: "xml",
success: parseXml,
complete: setupAC,
failure: function(data) {
alert("XML File could not be found");
}
});
function parseXml(xml)
{
//find every query value
$(xml).find("state").each(function()
{
//you are going to create an array of objects
var thisItem = {};
thisItem['label'] = $(this).attr("label") + ', ' + $(this).attr("country");
thisItem['value'] = $(this).attr("iata");
myArr.push(thisItem);
});
}
function setupAC() {
$("#city").autocomplete({
source: myArr,
minLength: 3,
select: function(event, ui) {
$("#city").val(ui.item.iata);
$("#qf").submit();
}
});
}
});
code part one airports.xml file snippet
<states>
<state label="London Heathrow" iata="LHR" country="UK" />
<state label="Syndey" iata="SYD" country="Australia" />
....
code part one search form snippet
<label for="city">From</label></td>
CODE PART TWO Here's the code for the autocomplete using JSON from geonames
$(function() {
function log( message ) {
$( "<div/>" ).text( message ).prependTo( "#log" );
$( "#log" ).attr( "scrollTop", 0 );
}
$( "#city" 开发者_如何学JAVA).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 20,
name_startsWith: request.term
},
success: function( data ) {
response( $.map( data.geonames, function( item ) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
});
I think you could merge the two dataset, in particular merge the results from the json call with the data taken from the excel. This is how i'd do it (i didn't use data from an excel but static data, but it should be the same);
var availableTags = [];
var london = { label: 'London Airport - UK', value: 'LHR'};
var paris= { label: 'Paris Airport - FRA', value: 'PAR'};
availableTags.push(london);
availableTags.push(paris);
$("#city2").autocomplete({
source: availableTags
});
function log( message ) {
$( "<div/>" ).text( message ).prependTo( "#log" );
$( "#log" ).attr( "scrollTop", 0 );
}
function filterArrayForString(string, array){
var results = [];
$.each(array, function(i, el){
var label= el.label;
if (label.toLowerCase().indexOf(string.toLowerCase()) !== -1){
results.push(el);
}
});
return results;
}
$( "#city" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 20,
name_startsWith: request.term
},
success: function( data ) {
var dataConv = $.map( data.geonames, function( item ) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
});
var filteredAvailable = filterArrayForString(request.term, availableTags );
console.log(request.term);
console.log(filteredAvailable);
var both = filteredAvailable.concat(dataConv);
response(both);
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
The merged data is in the both
variable, you could even sort it for a better result. Fiddle here: http://jsfiddle.net/7cLxD/7/ (write lo in the jsonP input and you'll se as the first result London taken from the static array)
精彩评论