Created
September 2, 2011 12:48
-
-
Save masylum/1188524 to your computer and use it in GitHub Desktop.
Autocomplete locations using yahoo woeid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*globals APP*/ | |
(function () { | |
var LOCATION = {} | |
, cache = {} | |
, jqXHR = null; | |
function _getCoords(place) { | |
return [ | |
place.centroid.latitude + ',' + place.centroid.longitude | |
, place.boundingBox.northEast.latitude + ',' + place.boundingBox.northEast.longitude | |
, place.boundingBox.southWest.latitude + ',' + place.boundingBox.southWest.longitude | |
].join(';'); | |
} | |
function _getAddress(place) { | |
if (place.name === place.country) { | |
return place.name; | |
} else if (place.name === place.admin1) { | |
return place.name + ', ' + place.country; | |
} else { | |
return place.name + ', ' + place.admin1 + ', ' + place.country; | |
} | |
} | |
function exports(options) { | |
var $address = options.address | |
, $name = options.name | |
, $country_iso = options.country_iso | |
, $is_city = options.is_city | |
, $coords = options.coords | |
, $autocomplete = $("<div class='autocomplete'></div>") | |
, $result = $("<div class='box'></div>").hide(); | |
LOCATION.options = options || {}; | |
LOCATION.options.autocomplete = $autocomplete; | |
LOCATION.options.result = $result; | |
LOCATION.options.name = $name; | |
LOCATION.options.country_iso = $country_iso; | |
LOCATION.options.is_city = $is_city; | |
LOCATION.options.coords = $coords; | |
$address.after($autocomplete); | |
$address.after($result); | |
function search(is_streamed) { | |
LOCATION.addressToSelector($address.val(), is_streamed); | |
} | |
$address | |
.keyup($.debounce(300, function (event) { | |
search(true); | |
})) | |
.keydown(function (event) { | |
if (event.keyCode === 13) { | |
event.preventDefault(); | |
search(false); | |
} | |
}); | |
if ($name.val() && $country_iso.val() && $address.val()) { | |
LOCATION.selectResult({ | |
address: $address.val() | |
, name: $name.val() | |
, country_iso: $country_iso.val() | |
, is_city: $is_city.val() | |
, coords: $coords.val() | |
}); | |
} else if ($address.val()) { | |
search(false); | |
} | |
return LOCATION; | |
} | |
LOCATION.addressToSelector = function (query, is_streamed) { | |
LOCATION.options.autocomplete.html("<img src='/images/spinner.gif' alt='loading' />").show(); | |
function onError() { | |
LOCATION.options.autocomplete.html('<div class="box warning">No ' + LOCATION.options.scope + ' found</div>'); | |
} | |
function onSuccess(results) { | |
var html = '' | |
, total = results.places.total | |
, places = results.places.place | |
, address; | |
cache[query] = results; | |
// not streamed and one place | |
if (total === 1 && !is_streamed) { | |
LOCATION.selectResult({ | |
address: _getAddress(places[0]) | |
, name: places[0].name | |
, country_iso: places[0]['country attrs'].code | |
, is_city: places[0]['placeTypeName attrs'].code === 7 | |
, coords: _getCoords(places[0]) | |
}); | |
// one or more place | |
} else if (total > 0) { | |
$.each(places, function (i, place) { | |
html += '<li><a href="#" data-name="' + place.name + '" data-country-iso="' | |
+ place['country attrs'].code + '" data-coords="' + _getCoords(place) + '"' | |
+ ' data-is-city="' + (place['placeTypeName attrs'].code === 7) + '">' | |
+ _getAddress(place) + '</a></li>'; | |
}); | |
LOCATION.options.autocomplete.html('<ul>' + html + '</ul>').show().find('li a').click(function () { | |
LOCATION.selectResult({ | |
address: $(this).text() | |
, name: $(this).attr('data-name') | |
, country_iso: $(this).attr('data-country-iso') | |
, is_city: $(this).attr('data-is-city') | |
, coords: $(this).attr('data-coords') | |
}); | |
return false; | |
}); | |
// without any place | |
} else { | |
onError(); | |
} | |
} | |
if (cache[query]) { | |
onSuccess(cache[query]); | |
} else { | |
// limit to one ajax call | |
if (jqXHR) { | |
jqXHR.abort(); | |
} | |
jqXHR = $.ajax({ | |
url: '/locations/' + LOCATION.options.scope + '/' + query.toLowerCase() | |
, type: 'get' | |
, success: onSuccess | |
, error: onError | |
}); | |
} | |
}; | |
LOCATION.selectResult = function (result) { | |
var options = LOCATION.options; | |
options.result.show().html(result.address + ' <a href="#" class="geonames_result_edit">» edit</a>'); | |
options.address.hide().val(result.address); | |
options.autocomplete.hide(); | |
options.name.val(result.name); | |
options.country_iso.val(result.country_iso); | |
options.is_city.val(result.is_city); | |
options.coords.val(result.coords).trigger('change'); | |
function onEdit() { | |
LOCATION.unselectResult(); | |
return false; | |
} | |
$('.geonames_result_edit').click(onEdit); | |
}; | |
LOCATION.unselectResult = function () { | |
var options = LOCATION.options; | |
options.address.show(); | |
options.result.hide().html(''); | |
options.country_iso.val(''); | |
options.name.val(''); | |
options.is_city.val(''); | |
options.coords.val(''); | |
}; | |
// exports | |
APP.modules.location = exports; | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment