vendor/assets/javascripts/gmaps-auto-complete.js in gmaps-autocomplete-rails-0.1.4 vs vendor/assets/javascripts/gmaps-auto-complete.js in gmaps-autocomplete-rails-0.2.0
- old
+ new
@@ -1,297 +1,157 @@
-var GmapsCompleter, GmapsCompleterDefaultAssist,
- __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+var geocoder;
+var map;
+var marker;
-GmapsCompleter = (function() {
- GmapsCompleter.prototype.geocoder = null;
+// initialise the google maps objects, and add listeners
+function gmaps_init(){
- GmapsCompleter.prototype.map = null;
+ // center of the universe
+ var latlng = new google.maps.LatLng(51.751724,-1.255284);
- GmapsCompleter.prototype.marker = null;
+ var options = {
+ zoom: 2,
+ center: latlng,
+ mapTypeId: google.maps.MapTypeId.ROADMAP
+ };
- GmapsCompleter.prototype.inputField = null;
+ // create our map object
+ map = new google.maps.Map(document.getElementById("gmaps-canvas"), options);
- GmapsCompleter.prototype.errorField = null;
+ // the geocoder object allows us to do latlng lookup based on address
+ geocoder = new google.maps.Geocoder();
- GmapsCompleter.prototype.positionOutputter = null;
+ // the marker shows us the position of the latest address
+ marker = new google.maps.Marker({
+ map: map,
+ draggable: true
+ });
- GmapsCompleter.prototype.updateUI = null;
+ // event triggered when marker is dragged and dropped
+ google.maps.event.addListener(marker, 'dragend', function() {
+ geocode_lookup( 'latLng', marker.getPosition() );
+ });
- GmapsCompleter.prototype.updateMap = null;
+ // event triggered when map is clicked
+ google.maps.event.addListener(map, 'click', function(event) {
+ marker.setPosition(event.latLng)
+ geocode_lookup( 'latLng', event.latLng );
+ });
- GmapsCompleter.prototype.region = null;
+ $('#gmaps-error').hide();
+}
- GmapsCompleter.prototype.country = null;
+// move the marker to a new position, and center the map on it
+function update_map( geometry ) {
+ map.fitBounds( geometry.viewport )
+ marker.setPosition( geometry.location )
+}
- GmapsCompleter.prototype.debugOn = false;
+// fill in the UI elements with new position data
+function update_ui( address, latLng ) {
+ $('#gmaps-input-address').autocomplete("close");
+ $('#gmaps-input-address').val(address);
+ //$('#gmaps-output-latitude').html(latLng.lat());
+ //$('#gmaps-output-longitude').html(latLng.lng());
+}
- GmapsCompleter.prototype.mapElem = null;
+// Query the Google geocode object
+//
+// type: 'address' for search by address
+// 'latLng' for search by latLng (reverse lookup)
+//
+// value: search query
+//
+// update: should we update the map (center map and position marker)?
+function geocode_lookup( type, value, update ) {
+ // default value: update = false
+ update = typeof update !== 'undefined' ? update : false;
- GmapsCompleter.prototype.zoomLevel = 2;
+ request = {};
+ request[type] = value;
- GmapsCompleter.prototype.mapType = null;
+ geocoder.geocode(request, function(results, status) {
+ $('#gmaps-error').html('');
+ $('#gmaps-error').hide();
+ if (status == google.maps.GeocoderStatus.OK) {
+ // Google geocoding has succeeded!
+ if (results[0]) {
+ // Always update the UI elements with new location data
+ update_ui( results[0].formatted_address,
+ results[0].geometry.location )
- GmapsCompleter.prototype.pos = [0, 0];
-
- GmapsCompleter.prototype.inputField = '#gmaps-input-address';
-
- GmapsCompleter.prototype.errorField = '#gmaps-error';
-
- function GmapsCompleter(opts) {
- this.keyDownHandler = __bind(this.keyDownHandler, this);
- this.performGeocode = __bind(this.performGeocode, this);
- this.init(opts);
- }
-
- GmapsCompleter.prototype.init = function(opts) {
- var callOpts, completerAssistClass, error, lat, latlng, lng, mapElem, mapOptions, mapType, pos, self, zoomLevel;
- opts = opts || {};
- callOpts = $.extend(true, {}, opts);
- this.debugOn = opts['debugOn'];
- this.debug('init(opts)', opts);
- completerAssistClass = opts['assist'];
- try {
- this.assist = new completerAssistClass;
- } catch (_error) {
- error = _error;
- this.debug('assist error', error, opts['assist']);
- }
- this.assist || (this.assist = new GmapsCompleterDefaultAssist);
- this.defaultOptions = opts['defaultOptions'] || this.assist.options;
- opts = $.extend(true, {}, this.defaultOptions, opts);
- this.positionOutputter = opts['positionOutputter'] || this.assist.positionOutputter;
- this.updateUI = opts['updateUI'] || this.assist.updateUI;
- this.updateMap = opts['updateMap'] || this.assist.updateMap;
- this.geocodeErrorMsg = opts['geocodeErrorMsg'] || this.assist.geocodeErrorMsg;
- this.geocodeErrorMsg = opts['geocodeErrorMsg'] || this.assist.geocodeErrorMsg;
- this.noAddressFoundMsg = opts['noAddressFoundMsg'] || this.assist.noAddressFoundMsg;
- pos = opts['pos'];
- lat = pos[0];
- lng = pos[1];
- mapType = opts['mapType'];
- mapElem = null;
- this.mapElem = $("gmaps-canvas");
- if (opts['mapElem']) {
- this.mapElem = $(opts['mapElem']).get(0);
- }
- this.mapType = google.maps.MapTypeId.ROADMAP;
- zoomLevel = opts['zoomLevel'];
- this.inputField = opts['inputField'];
- this.errorField = opts['#gmaps-error'];
- this.debugOn = opts['debugOn'];
- this.debug('called with opts', callOpts);
- this.debug('final completerAssist', this.completerAssist);
- this.debug('defaultOptions', this.defaultOptions);
- this.debug('options after merge with defaults', opts);
- latlng = new google.maps.LatLng(lat, lng);
- this.debug('lat,lng', latlng);
- mapOptions = {
- zoom: zoomLevel,
- center: latlng,
- mapTypeId: mapType
- };
- this.debug('map options', mapOptions);
- this.geocoder = new google.maps.Geocoder();
- self = this;
- if (typeof this.mapElem === 'undefined') {
- this.showError("Map element " + opts['mapElem'] + " could not be resolved!");
- }
- this.debug('mapElem', this.mapElem);
- if (!this.mapElem) {
- return;
- }
- this.map = new google.maps.Map(this.mapElem, mapOptions);
- if (!this.map) {
- return;
- }
- this.marker = new google.maps.Marker({
- map: this.map,
- draggable: true
- });
- return self.addMapListeners(this.marker, this.map);
- };
-
- GmapsCompleter.prototype.debug = function(label, obj) {
- if (!this.debugOn) {
- return;
- }
- return console.log(label, obj);
- };
-
- GmapsCompleter.prototype.addMapListeners = function(marker, map) {
- var self;
- self = this;
- google.maps.event.addListener(marker, 'dragend', function() {
- return self.geocodeLookup('latLng', marker.getPosition());
- });
- return google.maps.event.addListener(map, 'click', function(event) {
- marker.setPosition(event.latLng);
- return self.geocodeLookup('latLng', event.latLng);
- });
- };
-
- GmapsCompleter.prototype.geocodeLookup = function(type, value, update) {
- var request;
- this.update || (this.update = false);
- request = {};
- request[type] = value;
- return this.geocoder.geocode(request, this.performGeocode);
- };
-
- GmapsCompleter.prototype.performGeocode = function(results, status) {
- this.debug('performGeocode', status);
- $(this.errorField).html('');
- if (status === google.maps.GeocoderStatus.OK) {
- return this.geocodeSuccess(results);
- } else {
- return this.geocodeFailure(type, value);
- }
- };
-
- GmapsCompleter.prototype.geocodeSuccess = function(results) {
- this.debug('geocodeSuccess', results);
- if (results[0]) {
- this.updateUI(results[0].formatted_address, results[0].geometry.location);
- if (this.update) {
- return this.updateMap(results[0].geometry);
+ // Only update the map (position marker and center map) if requested
+ if( update ) { update_map( results[0].geometry ) }
+ } else {
+ // Geocoder status ok but no results!?
+ $('#gmaps-error').html("Sorry, something went wrong. Try again!");
+ $('#gmaps-error').show();
}
} else {
- return this.showError(this.geocodeErrorMsg());
- }
- };
+ // Google Geocoding has failed. Two common reasons:
+ // * Address not recognised (e.g. search for 'zxxzcxczxcx')
+ // * Location doesn't map to address (e.g. click in middle of Atlantic)
- GmapsCompleter.prototype.geocodeFailure = function(type, value) {
- this.debug('geocodeFailure', type);
- if (type === 'address') {
- return this.showError(this.invalidAddressMsg(value));
- } else {
- this.showError(this.noAddressFoundMsg());
- return this.updateUI('', value);
- }
- };
-
- GmapsCompleter.prototype.showError = function(msg) {
- $(this.errorField).html(msg);
- $(this.errorField).show();
- return setTimeout(function() {
- return $(this.errorField).hide();
- }, 1000);
- };
-
- GmapsCompleter.prototype.autoCompleteInit = function(opts) {
- var autocompleteOpts, defaultAutocompleteOpts, self;
- opts = opts || {};
- this.region = opts['region'] || this.defaultOptions['region'];
- this.country = opts['country'] || this.defaultOptions['country'];
- this.debug('region', this.region);
- self = this;
- autocompleteOpts = opts['autocomplete'] || {};
- defaultAutocompleteOpts = {
- select: function(event, ui) {
- self.updateUI(ui.item.value, ui.item.geocode.geometry.location);
- return self.updateMap(ui.item.geocode.geometry);
- },
- source: function(request, response) {
- var address, geocodeOpts, region, region_postfix;
- region_postfix = '';
- region = self.region;
- if (region) {
- region_postfix = ', ' + region;
- }
- address = request.term + region_postfix;
- self.debug('geocode address', address);
- geocodeOpts = {
- 'address': address
- };
- return self.geocoder.geocode(geocodeOpts, function(results, status) {
- return response($.map(results, function(item) {
- var uiAddress;
- uiAddress = item.formatted_address.replace(", " + self.country, '');
- return {
- label: uiAddress,
- value: uiAddress,
- geocode: item
- };
- }));
- });
+ if( type == 'address' ) {
+ // User has typed in an address which we can't geocode to a location
+ $('#gmaps-error').html("Sorry! We couldn't find " + value + ". Try a different search term, or click the map." );
+ $('#gmaps-error').show();
+ } else {
+ // User has clicked or dragged marker to somewhere that Google can't do a reverse lookup for
+ // In this case we display a warning, clear the address box, but fill in LatLng
+ $('#gmaps-error').html("Woah... that's pretty remote! You're going to have to manually enter a place name." );
+ $('#gmaps-error').show();
+ update_ui('', value)
}
};
- autocompleteOpts = $.extend(true, defaultAutocompleteOpts, autocompleteOpts);
- $(this.inputField).autocomplete(autocompleteOpts);
- return $(this.inputField).bind('keydown', this.keyDownHandler);
- };
+ });
+};
- GmapsCompleter.prototype.keyDownHandler = function(event) {
- if (event.keyCode === 13) {
- this.geocodeLookup('address', $(this.inputField).val(), true);
- return $(this.inputField).autocomplete("disable");
- } else {
- return $(this.inputField).autocomplete("enable");
- }
- };
+// initialise the jqueryUI autocomplete element
+function autocomplete_init() {
+ $("#gmaps-input-address").autocomplete({
- return GmapsCompleter;
+ // source is the list of input options shown in the autocomplete dropdown.
+ // see documentation: http://jqueryui.com/demos/autocomplete/
+ source: function(request,response) {
-})();
+ // the geocode method takes an address or LatLng to search for
+ // and a callback function which should process the results into
+ // a format accepted by jqueryUI autocomplete
+ geocoder.geocode( {'address': request.term }, function(results, status) {
+ response($.map(results, function(item) {
+ return {
+ label: item.formatted_address, // appears in dropdown box
+ value: item.formatted_address, // inserted into input element when selected
+ geocode: item // all geocode data: used in select callback event
+ }
+ }));
+ })
+ },
-GmapsCompleterDefaultAssist = (function() {
- function GmapsCompleterDefaultAssist() {}
+ // event triggered when drop-down option selected
+ select: function(event,ui){
+ update_ui( ui.item.value, ui.item.geocode.geometry.location )
+ update_map( ui.item.geocode.geometry )
+ }
+ });
- GmapsCompleterDefaultAssist.prototype.options = {
- mapElem: '#gmaps-canvas',
- zoomLevel: 2,
- mapType: google.maps.MapTypeId.ROADMAP,
- pos: [0, 0],
- inputField: '#gmaps-input-address',
- errorField: '#gmaps-error',
- debugOn: true
- };
+ // triggered when user presses a key in the address box
+ $("#gmaps-input-address").bind('keydown', function(event) {
+ if(event.keyCode == 13) {
+ geocode_lookup( 'address', $('#gmaps-input-address').val(), true );
- GmapsCompleterDefaultAssist.prototype.updateMap = function(geometry) {
- var map, marker;
- map = this.map;
- marker = this.marker;
- if (map) {
- map.fitBounds(geometry.viewport);
+ // ensures dropdown disappears when enter is pressed
+ $('#gmaps-input-address').autocomplete("disable")
+ } else {
+ // re-enable if previously disabled above
+ $('#gmaps-input-address').autocomplete("enable")
}
- if (marker) {
- return marker.setPosition(geometry.location);
- }
- };
+ });
+}; // autocomplete_init
- GmapsCompleterDefaultAssist.prototype.updateUI = function(address, latLng) {
- var country, inputField, updateAdr;
- inputField = this.inputField;
- country = this.country;
- $(inputField).autocomplete('close');
- this.debug('country', country);
- updateAdr = address.replace(', ' + country, '');
- updateAdr = address;
- this.debug('updateAdr', updateAdr);
- $(inputField).val(updateAdr);
- return this.positionOutputter(latLng);
+$(document).ready(function() {
+ if( $('#gmaps-canvas').length ) {
+ gmaps_init();
+ autocomplete_init();
};
-
- GmapsCompleterDefaultAssist.prototype.positionOutputter = function(latLng) {
- $('#gmaps-output-latitude').html(latLng.lat());
- return $('#gmaps-output-longitude').html(latLng.lng());
- };
-
- GmapsCompleterDefaultAssist.prototype.geocodeErrorMsg = function() {
- return "Sorry, something went wrong. Try again!";
- };
-
- GmapsCompleterDefaultAssist.prototype.invalidAddressMsg = function(value) {
- return "Sorry! We couldn't find " + value + ". Try a different search term, or click the map.";
- };
-
- GmapsCompleterDefaultAssist.prototype.noAddressFoundMsg = function() {
- return "Woah... that's pretty remote! You're going to have to manually enter a place name.";
- };
-
- return GmapsCompleterDefaultAssist;
-
-})();
-
-window.GmapsCompleter = GmapsCompleter;
-
-window.GmapsCompleterDefaultAssist = GmapsCompleterDefaultAssist;
+});
\ No newline at end of file