Improved location widget

This commit is contained in:
Martin Bauer 2013-09-27 11:39:28 +02:00
parent 11135b5592
commit 05b7a2b969
8 changed files with 74 additions and 94 deletions

Binary file not shown.

View File

@ -20,7 +20,7 @@ class Event ( models.Model ):
title = models.CharField( max_length=40, verbose_name = _("titel") ) title = models.CharField( max_length=40, verbose_name = _("titel") )
type = models.CharField( max_length=6, choices=EVENT_TYPES, default='Reh', verbose_name= _("type") ) type = models.CharField( max_length=6, choices=EVENT_TYPES, default='Reh', verbose_name= _("type") )
location = models.TextField( blank=False, verbose_name=_("location") ) location = models.TextField( blank=False, verbose_name=_("location") )
map_location = PlainLocationField( based_fields = [location], zoom=7 ) map_location = PlainLocationField( based_field = location, zoom=7 )
desc = models.TextField( blank=True, verbose_name=_("description")) desc = models.TextField( blank=True, verbose_name=_("description"))
date = models.DateField( verbose_name= _("date") ) date = models.DateField( verbose_name= _("date") )

View File

@ -3,12 +3,10 @@ from location_field.widgets import LocationWidget
class PlainLocationField(fields.CharField): class PlainLocationField(fields.CharField):
def __init__(self, based_fields=None, zoom=None, default=None, def __init__(self, based_field=None, zoom=None, default=None, *args, **kwargs):
*args, **kwargs):
kwargs['initial'] = default kwargs['initial'] = default
self.widget = LocationWidget(based_field=based_field, zoom=zoom, **kwargs)
self.widget = LocationWidget(based_fields=based_fields, zoom=zoom,
**kwargs)
dwargs = { dwargs = {
'required': True, 'required': True,

View File

@ -1,76 +1,66 @@
($ || django.jQuery)(function($){ ($ || django.jQuery)(function($){
function location_field_load(map, location_based, zoom) function location_field_load( map, base_field, initZoom )
{ {
var parent = map.parent().parent(); var parent = map.parent().parent();
var coordinate_field = parent.find('input[type=text]');
var location_map;
var map;
var location_coordinate = parent.find('input[type=text]'); var current_position;
function load() { //coordinate_field.hide();
var point = new google.maps.LatLng(49.340174,10.890595); coordinate_field.attr("readonly","readonly")
var options = { function load()
mapTypeId: google.maps.MapTypeId.HYBRID {
}; var options = { mapTypeId: google.maps.MapTypeId.HYBRID };
map = new google.maps.Map(map[0], options);
location_map = new google.maps.Map(map[0], options); if ( coordinate_field.val() ) // Already values in the coordinate field
var initial_position;
if (location_coordinate.val())
{ {
var l = location_coordinate.val().split(/,/); var l = coordinate_field.val().split(/,/);
if (l.length > 1) if (l.length > 1)
{ {
initial_position = new google.maps.LatLng(l[0], l[1]); current_position = new google.maps.LatLng(l[0], l[1]);
location_map.setZoom( parseInt(l[2]) ); map.setZoom( parseInt( l[2] ) );
} }
} }
else
if ( ! current_position )
{ {
location_map.setZoom(zoom); var locationRohr = new google.maps.LatLng( 49.340174,10.890595 );
current_position = locationRohr;
map.setZoom( initZoom );
} }
function savePosition( p ) {
function savePosition( p ) current_position = p;
{ coordinate_field.val( current_position.lat().toFixed(6) + "," + current_position.lng().toFixed(6) + "," + map.getZoom() );
point = p; }
location_coordinate.val(point.lat().toFixed(6) + "," + point.lng().toFixed(6) + "," + location_map.getZoom() );
} var marker = new google.maps.Marker({
map: map,
var marker = new google.maps.Marker({ position: current_position,
map: location_map, draggable: true
position: initial_position, });
draggable: true
});
google.maps.event.addListener(marker, 'dragend', function(mouseEvent) { google.maps.event.addListener(marker, 'dragend', function(mouseEvent) {
savePosition(mouseEvent.latLng); savePosition(mouseEvent.latLng);
}); });
google.maps.event.addListener(location_map, 'click', function(mouseEvent){ google.maps.event.addListener(map, 'click', function(mouseEvent){
marker.setPosition(mouseEvent.latLng); marker.setPosition(mouseEvent.latLng);
savePosition(mouseEvent.latLng); savePosition( mouseEvent.latLng );
}); });
google.maps.event.addListener(location_map, 'zoom_changed', function(mouseEvent){ google.maps.event.addListener(map, 'zoom_changed', function(mouseEvent){
savePosition(point); savePosition( current_position );
}); });
location_based.bindWithDelay("keypress", function() { base_field.bindWithDelay( "keypress", function() {
var lstr = [];
location_based.each(function(){
var b = $(this);
lstr.push(b.val())
});
geocode(lstr.join(','), function(l){ geocode( base_field.val() , function(l){
location_coordinate.val( l.lat()+','+l.lng() ); coordinate_field.val( l.lat()+','+l.lng() );
}); });
onLocationCoordinateChange(); onLocationCoordinateChange();
}, 2000 ); }, 2000 );
@ -79,19 +69,16 @@
{ {
var latlng = jQuery(this).val().split(/,/); var latlng = jQuery(this).val().split(/,/);
if (latlng.length < 2) return; if (latlng.length < 2) return;
var latlng = new google.maps.LatLng(latlng[0], latlng[1]); var latlng = new google.maps.LatLng( latlng[0], latlng[1] );
placeMarker( latlng ); placeMarker( latlng );
location_map.setZoom( latlng[2] ); map.setZoom( latlng[2] );
//geocode_reverse(latlng, function(l){
// location_coordinate.val(l.lat()+','+l.lng());
//});
} }
function placeMarker(location) { function placeMarker(location) {
marker.setPosition(location); marker.setPosition(location);
location_map.setCenter(location); map.setCenter(location);
savePosition(location); savePosition(location);
location_map.panTo(location); map.panTo(location);
} }
function geocode(address, cb) { function geocode(address, cb) {
@ -119,21 +106,22 @@
} }
}*/ }*/
placeMarker( current_position );
placeMarker(initial_position);
} }
load(); load();
} }
$('input[data-location-widget]').each(function(){ $('input[data-location-widget]').each(function(){
var $el = $(this); var $el = $(this);
var $map = $($el.attr('data-map')), var $map = $($el.attr('data-map')),
$based_fields = $($el.attr('data-based-fields')), $based_field = $(($el.attr('data-based-field'))),
zoom = parseInt($el.attr('data-zoom')); zoom = parseInt($el.attr('data-zoom'));
location_field_load($map, $based_fields, zoom); location_field_load( $map, $based_field, zoom );
}); });
}); });

View File

@ -4,8 +4,8 @@ from location_field import forms
class BaseLocationField(object): class BaseLocationField(object):
def __init__(self, based_fields=[], zoom=2, default=None, *args, **kwargs): def __init__(self, based_field=None, zoom=2, default=None, *args, **kwargs):
self._based_fields = based_fields self._based_field = based_field
self._zoom = zoom self._zoom = zoom
self._default = default self._default = default
self.default = default self.default = default
@ -13,7 +13,7 @@ class BaseLocationField(object):
def formfield(self, **kwargs): def formfield(self, **kwargs):
return super(BaseLocationField, self).formfield( return super(BaseLocationField, self).formfield(
form_class=self.formfield_class, form_class=self.formfield_class,
based_fields=self._based_fields, based_field=self._based_field,
zoom=self._zoom, zoom=self._zoom,
default=self._default, default=self._default,
**kwargs) **kwargs)
@ -22,10 +22,10 @@ class BaseLocationField(object):
class PlainLocationField(BaseLocationField, CharField): class PlainLocationField(BaseLocationField, CharField):
formfield_class = forms.PlainLocationField formfield_class = forms.PlainLocationField
def __init__(self, based_fields=None, zoom=None, def __init__(self, based_field=None, zoom=None,
max_length=63, *args, **kwargs): max_length=63, *args, **kwargs):
super(PlainLocationField, self).__init__(based_fields=based_fields, super(PlainLocationField, self).__init__(based_field=based_field,
zoom=zoom, *args, **kwargs) zoom=zoom, *args, **kwargs)
CharField.__init__(self, max_length=max_length, *args, **kwargs) CharField.__init__(self, max_length=max_length, *args, **kwargs)

View File

@ -1 +0,0 @@
# Create your views here.

View File

@ -1,11 +1,12 @@
from django.forms import widgets from django.forms import widgets
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
class LocationWidget(widgets.TextInput): class LocationWidget(widgets.TextInput):
def __init__(self, attrs=None, based_fields=None, zoom=None, **kwargs): def __init__(self, attrs=None, based_field=None, zoom=None, width=610, height = 480, **kwargs):
self.based_fields = based_fields self.based_field = based_field
self.zoom = zoom self.zoom = zoom
self.width = width
self.height = height
super(LocationWidget, self).__init__(attrs) super(LocationWidget, self).__init__(attrs)
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
@ -20,29 +21,23 @@ class LocationWidget(widgets.TextInput):
else: else:
value = '' value = ''
if '-' not in name: based_field = "#id_" + self.based_field.name
prefix = ''
else:
prefix = name[:name.rindex('-') + 1]
based_fields = ','.join(
map(lambda f: '#id_' + prefix + f.name, self.based_fields))
attrs = attrs or {} attrs = attrs or {}
attrs['data-location-widget'] = name attrs['data-location-widget'] = name
attrs['data-based-fields'] = based_fields attrs['data-based-field'] = based_field
attrs['data-zoom'] = self.zoom attrs['data-zoom'] = self.zoom
attrs['data-map'] = '#map_' + name attrs['data-map'] = '#map_' + name
text_input = super(LocationWidget, self).render(name, value, attrs) text_input = super(LocationWidget, self).render(name, value, attrs)
map_div = u''' map_div = u'''
<div style="margin:4px 0 0 0"> <div style="margin:4px 0 0 0"> <label></label>
<label></label> <div id="map_%(name)s" style="width: %(width)dpx; height: %(height)dpx"></div>
<div id="map_%(name)s" style="width: 610px; height: 350px"></div> </div>
</div> '''
'''
return mark_safe(text_input + map_div % {'name': name}) return mark_safe(text_input + map_div % {'name': name, 'width': self.width, 'height': self.height })
class Media: class Media:
# Use schemaless URL so it works with both, http and https websites # Use schemaless URL so it works with both, http and https websites

View File

@ -84,7 +84,7 @@
controlText.innerHTML = 'Konzertort anzeigen'; controlText.innerHTML = 'Konzertort anzeigen';
controlUI.appendChild(controlText); controlUI.appendChild(controlText);
var target = new google.maps.LatLng( {{routeInfo.destination}} ); var target = new google.maps.LatLng( {{ nextConcert.map_location }} );
google.maps.event.addDomListener(controlUI, 'click', function() { google.maps.event.addDomListener(controlUI, 'click', function() {
map.setMapTypeId( google.maps.MapTypeId.HYBRID ); map.setMapTypeId( google.maps.MapTypeId.HYBRID );