Created
December 13, 2010 14:48
-
-
Save bartek/739049 to your computer and use it in GitHub Desktop.
A simple Google Map Widget with a lat/lng marker. JS file included and required.
This file contains hidden or 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
/* | |
* A simple Google maps Javascript widget which will display a map and | |
* a marker with the ability to move the marker, then setting the | |
* lat/lng of the marker into the specified (or default) fields. | |
*/ | |
var google_map_location = new function() { | |
var jQuery; | |
var init_options; | |
var geocoder; | |
var map, marker, latlng; | |
/* | |
* Options available: | |
* zoom: zoom level of map (default: 14) | |
* lat: initial lat of map | |
* lng: initial lng of map | |
* markerMovedCallback: callback function to use when marker is moved to populate a lat field. | |
*/ | |
this.init = function(options) { | |
// Work around for when we have to use closures through django admin to pass in the jQuery object. | |
jQuery = options.jQuery || $; | |
init_options = options; | |
latlng = new google.maps.LatLng( | |
options.lat || 49.891235, | |
options.lng || -97.15369 | |
); | |
var myOptions = { | |
zoom: options.zoom || 14, | |
center: latlng, | |
mapTypeId: google.maps.MapTypeId.ROADMAP | |
}; | |
map = new google.maps.Map(document.getElementById('map_canvas'), | |
myOptions); | |
marker = new google.maps.Marker({ | |
position: latlng, | |
map: map, | |
draggable: true, | |
animation: google.maps.Animation.DROP | |
}); | |
this.bindHandlers(); | |
// Attempt to get an initialLocation. | |
if (options.geolocate && navigator.geolocation) { | |
browserSupportFlag = true; | |
navigator.geolocation.getCurrentPosition(this.hasPosition, this.noPosition); | |
} | |
} | |
// Once we have received a poistion, center our map and marker to it. | |
this.hasPosition = function(position) { | |
latlng = new google.maps.LatLng(position.coords.latitude, | |
position.coords.longitude); | |
map.setCenter(latlng); | |
marker.setPosition(latlng) | |
} | |
// If we have nothing, just show a friendly message | |
this.noPosition = function(error) { | |
jQuery("#map_message").html("Could not get current location. Please place marker over the Places location."); | |
} | |
/* | |
* Accept an input field that contains a val() object from jQuery and tries to encode | |
* an address from it. | |
*/ | |
this.codeAddress = function(field) { | |
var self = this; | |
geocoder = new google.maps.Geocoder(); | |
geocoder.geocode({'address': field.val()}, function(results, status) { | |
map.setCenter(results[0].geometry.location); | |
marker.setPosition(results[0].geometry.location); | |
self.populateLatLngFields(results[0].geometry.location); | |
}); | |
} | |
this.populateLatLngFields = function(point) { | |
jQuery("#id_lat").val(point.lat()); | |
jQuery("#id_lon").val(point.lng()); | |
}; | |
this.bindHandlers = function() { | |
var self = this; | |
google.maps.event.addListener(marker, 'dragend', function() { | |
var point = marker.getPosition(); | |
if(init_options.markerMovedCallback) { | |
init_options.markerMovedCallback(point); | |
} else { | |
self.populateLatLngFields(point); | |
} | |
}); | |
}; | |
}; |
This file contains hidden or 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
from django.forms.widgets import Input | |
from django.utils.safestring import mark_safe | |
class GoogleMapWidget(Input): | |
""" | |
Widget to display a Google Map on a page with the ability to move a marker | |
around and fetch coordinates. | |
""" | |
class Media: | |
js = ( | |
'http://maps.google.com/maps/api/js?sensor=true', | |
'static/js/google_map_location.js', | |
) | |
def render(self, name, value, attrs=None): | |
""" | |
Attribute extras: | |
width: width of the Google Map in pixels or percent. Must be the full string. | |
height: height of the Google Map in pixels or percent. Must be the full string. | |
markerMovedCallback: incase we don't want to populate the two default fields, let them specify their own callback. | |
center: (lat, lng) coordinates in tuple format. If not provided, will auto-detect location if available. | |
geolocate: Boolean. Default = True, If False, will not do any geolocation. Should be set to False if you provide a center() attribute | |
you do not want potentially over-ridden. | |
""" | |
# Defaults, can be overriden by any same-key passed through `attrs` | |
final_attrs = self.build_attrs(attrs) | |
context = { | |
'width': '600px', | |
'height': '300px', | |
'markerMovedCallback': 'null', | |
'lat': 'null', | |
'lng': 'null', | |
'geolocate': 'true', | |
} | |
context.update(final_attrs) | |
if 'center' in final_attrs: | |
context['lat'], context['lng'] = final_attrs['center'] | |
html = u''' | |
<input type='text' style='width: 400px;' id='map_search_text' /> <input type='button' id='map_search' value='Search' /> | |
<div id="map_canvas" style='width: %(width)s; height: %(height)s;'></div> | |
<div id="map_message">Marker has been placed near the coordinates of your current location. Please adjust it to match the Places location.</div> | |
<script type="text/javascript"> | |
//<![CDATA[ | |
var call_google_map = function(jQuery) { | |
google_map_location.init({ | |
'jQuery': jQuery, | |
markerMovedCallback: %(markerMovedCallback)s, | |
lat: %(lat)s, | |
lng: %(lng)s, | |
geolocate: %(geolocate)s | |
}); | |
// Add some event handlers for our search box. | |
jQuery("#map_search").click(function() { | |
google_map_location.codeAddress(jQuery("#map_search_text")); | |
}); | |
jQuery("#map_search_text").keypress(function(e) { | |
if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) { | |
google_map_location.codeAddress(jQuery(this)); | |
return false; | |
} | |
}); | |
} | |
// Do a simple check to see if we're using this widget in the admin. | |
if (typeof django != 'undefined') { | |
(function($) { | |
call_google_map($); | |
})(django.jQuery); | |
} else { | |
call_google_map($); | |
} | |
//]]> | |
</script> | |
''' % context | |
return mark_safe(html) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment