Louis Louis - 4 months ago 70
jQuery Question

Jquery / Json UI autocomplete Airport code

Im trying to use a Web Service to set an Airport code using Jquery UI autocomplete:

The WS is:
http://airportcode.riobard.com - http://airportcode.riobard.com/search?q=dallas&fmt=JSON

I can't create the autocomplete, here is my javascript code:

<script>
$(function() {
function log( message ) {
$( "<div/>" ).text( message ).prependTo( "#log" );
$( "#log" ).scrollTop( 0 );
}

$( "#city" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://airportcode.riobard.com",
dataType: "jsonp",
data: {
fmt: "JSONP",
q: request.term
},
success: function( data ) {
response( $.map( data.geonames, function( item ) {
return {
label: item.code + (item.name ? ", " + item.location : "") + ", " + item.location,
value: item.code
}
}));
}
});
},
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" );
}
});
});
</script>




<!-- HTML Code is -->

<div class="demo">

<div class="ui-widget">
<label for="city">Your city: </label>
<input id="city" />

</div>

<div class="ui-widget" style="margin-top:2em; font-family:Arial">
Result:
<div id="log" style="height: 50px; width: 200px; overflow: auto;" class="ui-widget-content"></div>
</div>

</div><!-- End demo -->

Answer

First off, the data source you're using does not support JSONP. You can't just grab an arbitrary JSON data source and tell jQuery it's JSONP and expect it to work. The server must be configured to take a callback argument that it appends to the response, calling your code when it completes and is injected onto the page.

You can get around this by using YQL or writing your own server-side code that calls the service.

Here's an example using YQL:

function buildQuery(term) {
    return "select * from json where url = 'http://airportcode.riobard.com/search?fmt=JSON&q=" + encodeURI(term) + "'";
}

function makeRequest(request, response) {
    $.ajax({
        url: 'http://query.yahooapis.com/v1/public/yql',
        data: {
            q: buildQuery(request.term),
            format: "json"
        },
        dataType: "jsonp",
        success: function(data) {
            var airports = [];
            if (data && data.query && data.query.results && data.query.results.json && data.query.results.json.json) {
                airports = data.query.results.json.json;
            }

            response($.map(airports, function(item) {
                return {
                    label: item.code + (item.name ? ", " + item.location : "") + ", " + item.location,
                    value: item.code
                };
            }));
        },
        error: function () {
            response([]);
        }
    });
}

$(document).ready(function() {
    $("#airport").autocomplete({
        source: makeRequest,
        minLength: 2
    });
});​

So instead of calling the web service directly, we'll ask YQL to make the request and return a result. YQL acts as a wrapper, making an otherwise inaccessible web service accessible via JSONP.

In the success method, we have to go through several properties to finally access the data. After we do that, we can format the results in a way that the autocomplete widget expects (with $.map).

Example: http://jsfiddle.net/BQxw4/40/

Comments