Skip to content

Commit

Permalink
re-factored geo-autocomplete widget to accept some more useful option…
Browse files Browse the repository at this point in the history
…s. more demos added.
  • Loading branch information
hitching committed Oct 7, 2010
1 parent e318c20 commit 37c3506
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 79 deletions.
68 changes: 38 additions & 30 deletions demo/ui.demo.html
@@ -1,56 +1,64 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>

<title>jQuery geo_Autocomplete Plugin</title>
<title>geo-autocomplete demos</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<link type="text/css" href="../lib/jquery-ui/css/ui-lightness/jquery-ui-1.8.5.custom.css" rel="Stylesheet" />
<script type="text/javascript" src="../lib/jquery-ui/js/jquery-ui-1.8.5.custom.min.js"></script>
<script type="text/javascript" src="../ui.geo_autocomplete.js"></script>

<script type="text/javascript">
$().ready(function() {
demo1();
demo2();
demo3();
demo4();
});

function demo1() {
$('#demo1_location').geo_autocomplete();
}

var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

// use all the autocomplete options as documented at http://jqueryui.com/demos/autocomplete
/* additional geo_autocomplete options:
map: the google.maps.Map object to relocate
mapwidth : 100
mapheight : 100
maptype : 'terrain' (see http://code.google.com/apis/maps/documentation/staticmaps/#MapTypes)
mapsensor : true or false
*/
$('#location').geo_autocomplete({
// this example relocates the map
select: function(event, ui) {
if (ui.item.viewport) map.fitBounds(ui.item.viewport);
// the select function uses the viewport of the chosen location to relocate the map
function demo2() {
var map = new google.maps.Map(document.getElementById("demo2_map"), { mapTypeId: google.maps.MapTypeId.ROADMAP });

$('#demo2_location').geo_autocomplete({
select: function(_event, _ui) {
if (_ui.item.viewport) map.fitBounds(_ui.item.viewport);
}
});
});
}

function demo3() {
$('#demo3_location').geo_autocomplete({
geocoder_region: 'Africa',
geocoder_types: 'country',
mapheight: 100, mapwidth: 200, maptype: 'hybrid'
});
}

</script>

<link type="text/css" href="../lib/jquery-ui/css/ui-lightness/jquery-ui-1.8.5.custom.css" rel="stylesheet" />
<style type="text/css">
.ui-autocomplete { overflow-y: auto; width:300px; }
* html .ui-autocomplete { /* IE max- */height: expression( this.scrollHeight > 320 ? "320px" : "auto" ); }
.ui-autocomplete { max-height: 320px; }
.ui-autocomplete li { font-size:10pt; }
</style>

</head>
<body>
<h3><a href="http://code.google.com/p/geo-autocomplete">jQuery geo-autocomplete Plugin</a> Demo</h3>
<h1>geo-autocomplete demos</h1>
<h3>Basic use</h3>
<p>Location: <input type="text" id="demo1_location" size="50" /></p>

<p>Updated 6 Oct 2010: Now built upon jQuery UI Autocomplete. You can still try the <a href="index.html">previous version</a>.</p>
<h3>Fast map relocation</h3>
<p>Location: <input type="text" id="demo2_location" size="50" /></p>
<div id="demo2_map" style="width:400px;height:300px;"></div>

<div>Location: <input type="text" id="location" /> (autocomplete)</div>
<br/>
<div id="map_canvas" style="width:500px;height:350px;"/>
<h3>Restricted to Countries within Africa</h3>
<p>Location: <input type="text" id="demo3_location" size="50" /></p>

</body>
</html>
112 changes: 63 additions & 49 deletions ui.geo_autocomplete.js
@@ -1,5 +1,5 @@
/*
* jQuery geo_autocomplete plugin 2.0
* jQuery geo_autocomplete plugin 2.0.1
*
* Copyright (c) 2010 Bob Hitching
*
Expand All @@ -11,65 +11,79 @@
*
*/
$.widget( "ui.geo_autocomplete", {
_geocoder: new google.maps.Geocoder, // shared by all geo_autocomplete widgets
_cache: {}, // common cache of results

// setup the element as an autocomplete widget with some geo goodness added
_init: function() {
var self = this;
this.options._geocoder = new google.maps.Geocoder, // geocoder object
this.options._cache = {}; // cache of geocoder responses
this.element.autocomplete(this.options);

// _renderItem is used to prevent the widget framework from escaping the HTML required to show the static map thumbnail
this.element.data('autocomplete')._renderItem = function(_ul, _item) {
return $('<li></li>').data('item.autocomplete', _item).append(this.options.getItemHTML(_item)).appendTo(_ul);
};
},

this.element.autocomplete($.extend({}, this.options, {
source: function(request, response) {
if (request.term in self._cache) {
response(self._cache[request.term]);
} else {
self._geocoder.geocode({'address': request.term}, function(_results, _status) {
var _parsed = [];
if (_results && _status && _status == 'OK') {
$.each(_results, function(_key, _result) {
if (_result.geometry && _result.geometry.viewport) {
// default values
options: {
geocoder_region: '', // filter to a specific region, e.g. 'Europe'
geocoder_types: 'locality,political,sublocality,neighborhood,country', // array of acceptable location types, see http://code.google.com/apis/maps/documentation/javascript/services.html#GeocodingAddressTypes
geocoder_address: false, // true = use the full formatted address, false = use only the segment that matches the search term

mapwidth: 100, // width of static map thumbnail
mapheight: 100, // height of static map thumbnail
maptype: 'terrain', // see http://code.google.com/apis/maps/documentation/staticmaps/#MapTypes
mapsensor: false, // see http://code.google.com/apis/maps/documentation/staticmaps/#Sensor

minLength: 3, // see http://jqueryui.com/demos/autocomplete/#option-minLength
delay: 300, // see http://jqueryui.com/demos/autocomplete/#option-delay
// callback function to get autocomplete results
source: function(_request, _response) {
if (_request.term in this.options._cache) {
_response(this.options._cache[_request.term]);
} else {
var self = this;
var _address = _request.term + (this.options.geocoder_region ? ', ' + this.options.geocoder_region : '');
this.options._geocoder.geocode({'address': _address}, function(_results, _status) {
var _parsed = [];
if (_results && _status && _status == 'OK') {
var _types = self.options.geocoder_types.split(',');
$.each(_results, function(_key, _result) {
// if this is an acceptable location type with a viewport, it's a good result
if ($.map(_result.types, function(_type) {
return $.inArray(_type, _types) != -1 ? _type : null;
}).length && _result.geometry && _result.geometry.viewport) {

if (self.options.geocoder_address) {
_place = _result.formatted_address;
} else {
// place is first matching segment, or first segment
var _place_parts = _result.formatted_address.split(',');
var _place = _place_parts[0];
$.each(_place_parts, function(_key, _part) {
if (_part.toLowerCase().indexOf(request.term.toLowerCase()) != -1) {
if (_part.toLowerCase().indexOf(_request.term.toLowerCase()) != -1) {
_place = $.trim(_part);
return false; // break
}
});

_parsed.push({
viewport: _result.geometry.viewport,
value: _place,
label: _result.formatted_address
});
}
});
}
self._cache[request.term] = _parsed;
response(_parsed);
});
}

_parsed.push({
value: _place,
label: _result.formatted_address,
viewport: _result.geometry.viewport
});
}
});
}
self.options._cache[_request.term] = _parsed;
_response(_parsed);
});
}
}));

this.element.data( "autocomplete" )._renderItem = function( ul, item ) {
var _src = 'http://maps.google.com/maps/api/staticmap?visible=' + item.viewport.getSouthWest().toUrlValue() + '|' + item.viewport.getNorthEast().toUrlValue() + '&size=' + self.options.mapwidth + 'x' + self.options.mapheight + '&maptype=' + self.options.maptype + '&sensor=' + (self.options.mapsensor ? 'true' : 'false');
var _place = item.label.replace(/,/gi, ',<br/>');

return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( '<a><img style="float:left;margin-right:5px;" src="' + _src + '" width="' + self.options.mapwidth + '" height="' + self.options.mapheight + '" /> ' + _place + '<br clear="both" /></a>' )
.appendTo( ul );
};
},

// default values
options: {
mapwidth: 100,
mapheight: 100,
maptype: 'terrain',
mapsensor: false,
minLength: 3,
delay: 300
},
// returns the HTML used for each autocomplete list item
getItemHTML: function(_item) {
var _src = 'http://maps.google.com/maps/api/staticmap?visible=' + _item.viewport.getSouthWest().toUrlValue() + '|' + _item.viewport.getNorthEast().toUrlValue() + '&size=' + this.mapwidth + 'x' + this.mapheight + '&maptype=' + this.maptype + '&sensor=' + (this.mapsensor ? 'true' : 'false');
return '<a><img style="float:left;margin-right:5px;" src="' + _src + '" width="' + this.mapwidth + '" height="' + this.mapheight + '" /> ' + _item.label.replace(/,/gi, ',<br/>') + '<br clear="both" /></a>'
}
}
});

0 comments on commit 37c3506

Please sign in to comment.