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") )
type = models.CharField( max_length=6, choices=EVENT_TYPES, default='Reh', verbose_name= _("type") )
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"))
date = models.DateField( verbose_name= _("date") )

View File

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

View File

@ -1,76 +1,66 @@
($ || 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 current_position;
var location_coordinate = parent.find('input[type=text]');
//coordinate_field.hide();
coordinate_field.attr("readonly","readonly")
function load() {
var point = new google.maps.LatLng(49.340174,10.890595);
function load()
{
var options = { mapTypeId: google.maps.MapTypeId.HYBRID };
map = new google.maps.Map(map[0], options);
var options = {
mapTypeId: google.maps.MapTypeId.HYBRID
};
location_map = new google.maps.Map(map[0], options);
var initial_position;
if (location_coordinate.val())
if ( coordinate_field.val() ) // Already values in the coordinate field
{
var l = location_coordinate.val().split(/,/);
var l = coordinate_field.val().split(/,/);
if (l.length > 1)
{
initial_position = new google.maps.LatLng(l[0], l[1]);
location_map.setZoom( parseInt(l[2]) );
current_position = new google.maps.LatLng(l[0], l[1]);
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 ) {
current_position = p;
coordinate_field.val( current_position.lat().toFixed(6) + "," + current_position.lng().toFixed(6) + "," + map.getZoom() );
}
function savePosition( p )
{
point = p;
location_coordinate.val(point.lat().toFixed(6) + "," + point.lng().toFixed(6) + "," + location_map.getZoom() );
}
var marker = new google.maps.Marker({
map: location_map,
position: initial_position,
draggable: true
});
var marker = new google.maps.Marker({
map: map,
position: current_position,
draggable: true
});
google.maps.event.addListener(marker, 'dragend', function(mouseEvent) {
savePosition(mouseEvent.latLng);
});
google.maps.event.addListener(location_map, 'click', function(mouseEvent){
google.maps.event.addListener(map, 'click', function(mouseEvent){
marker.setPosition(mouseEvent.latLng);
savePosition(mouseEvent.latLng);
savePosition( mouseEvent.latLng );
});
google.maps.event.addListener(location_map, 'zoom_changed', function(mouseEvent){
savePosition(point);
google.maps.event.addListener(map, 'zoom_changed', function(mouseEvent){
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( base_field.val() , function(l){
coordinate_field.val( l.lat()+','+l.lng() );
});
geocode(lstr.join(','), function(l){
location_coordinate.val( l.lat()+','+l.lng() );
});
onLocationCoordinateChange();
}, 2000 );
@ -79,19 +69,16 @@
{
var latlng = jQuery(this).val().split(/,/);
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 );
location_map.setZoom( latlng[2] );
//geocode_reverse(latlng, function(l){
// location_coordinate.val(l.lat()+','+l.lng());
//});
map.setZoom( latlng[2] );
}
function placeMarker(location) {
marker.setPosition(location);
location_map.setCenter(location);
map.setCenter(location);
savePosition(location);
location_map.panTo(location);
map.panTo(location);
}
function geocode(address, cb) {
@ -119,8 +106,7 @@
}
}*/
placeMarker(initial_position);
placeMarker( current_position );
}
load();
@ -131,9 +117,11 @@
var $el = $(this);
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'));
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):
def __init__(self, based_fields=[], zoom=2, default=None, *args, **kwargs):
self._based_fields = based_fields
def __init__(self, based_field=None, zoom=2, default=None, *args, **kwargs):
self._based_field = based_field
self._zoom = zoom
self._default = default
self.default = default
@ -13,7 +13,7 @@ class BaseLocationField(object):
def formfield(self, **kwargs):
return super(BaseLocationField, self).formfield(
form_class=self.formfield_class,
based_fields=self._based_fields,
based_field=self._based_field,
zoom=self._zoom,
default=self._default,
**kwargs)
@ -22,10 +22,10 @@ class BaseLocationField(object):
class PlainLocationField(BaseLocationField, CharField):
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):
super(PlainLocationField, self).__init__(based_fields=based_fields,
super(PlainLocationField, self).__init__(based_field=based_field,
zoom=zoom, *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.utils.safestring import mark_safe
class LocationWidget(widgets.TextInput):
def __init__(self, attrs=None, based_fields=None, zoom=None, **kwargs):
self.based_fields = based_fields
def __init__(self, attrs=None, based_field=None, zoom=None, width=610, height = 480, **kwargs):
self.based_field = based_field
self.zoom = zoom
self.width = width
self.height = height
super(LocationWidget, self).__init__(attrs)
def render(self, name, value, attrs=None):
@ -20,29 +21,23 @@ class LocationWidget(widgets.TextInput):
else:
value = ''
if '-' not in name:
prefix = ''
else:
prefix = name[:name.rindex('-') + 1]
based_fields = ','.join(
map(lambda f: '#id_' + prefix + f.name, self.based_fields))
based_field = "#id_" + self.based_field.name
attrs = attrs or {}
attrs['data-location-widget'] = name
attrs['data-based-fields'] = based_fields
attrs['data-based-field'] = based_field
attrs['data-zoom'] = self.zoom
attrs['data-map'] = '#map_' + name
text_input = super(LocationWidget, self).render(name, value, attrs)
map_div = u'''
<div style="margin:4px 0 0 0">
<label></label>
<div id="map_%(name)s" style="width: 610px; height: 350px"></div>
</div>
'''
return mark_safe(text_input + map_div % {'name': name})
<div style="margin:4px 0 0 0"> <label></label>
<div id="map_%(name)s" style="width: %(width)dpx; height: %(height)dpx"></div>
</div>
'''
return mark_safe(text_input + map_div % {'name': name, 'width': self.width, 'height': self.height })
class Media:
# Use schemaless URL so it works with both, http and https websites

View File

@ -84,7 +84,7 @@
controlText.innerHTML = 'Konzertort anzeigen';
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() {
map.setMapTypeId( google.maps.MapTypeId.HYBRID );