Addressbook
- location field.. has to be refactored
This commit is contained in:
0
location_field/__init__.py
Executable file
0
location_field/__init__.py
Executable file
28
location_field/forms.py
Normal file
28
location_field/forms.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from django.forms import fields
|
||||
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
|
||||
|
||||
self.widget = LocationWidget(based_fields=based_fields, zoom=zoom,
|
||||
**kwargs)
|
||||
|
||||
dwargs = {
|
||||
'required': True,
|
||||
'label': None,
|
||||
'initial': None,
|
||||
'help_text': None,
|
||||
'error_messages': None,
|
||||
'show_hidden_initial': False,
|
||||
}
|
||||
|
||||
for attr in dwargs:
|
||||
if attr in kwargs:
|
||||
dwargs[attr] = kwargs[attr]
|
||||
|
||||
super(PlainLocationField, self).__init__(*args, **dwargs)
|
||||
|
||||
|
||||
139
location_field/media/form.js
Normal file
139
location_field/media/form.js
Normal file
@@ -0,0 +1,139 @@
|
||||
($ || django.jQuery)(function($){
|
||||
function location_field_load(map, location_based, zoom)
|
||||
{
|
||||
var parent = map.parent().parent();
|
||||
|
||||
var location_map;
|
||||
|
||||
var location_coordinate = parent.find('input[type=text]');
|
||||
|
||||
function load() {
|
||||
var point = new google.maps.LatLng(49.340174,10.890595);
|
||||
|
||||
var options = {
|
||||
mapTypeId: google.maps.MapTypeId.HYBRID
|
||||
};
|
||||
|
||||
location_map = new google.maps.Map(map[0], options);
|
||||
|
||||
var initial_position;
|
||||
|
||||
if (location_coordinate.val())
|
||||
{
|
||||
var l = location_coordinate.val().split(/,/);
|
||||
|
||||
if (l.length > 1)
|
||||
{
|
||||
initial_position = new google.maps.LatLng(l[0], l[1]);
|
||||
location_map.setZoom( parseInt(l[2]) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
location_map.setZoom(zoom);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
google.maps.event.addListener(marker, 'dragend', function(mouseEvent) {
|
||||
savePosition(mouseEvent.latLng);
|
||||
});
|
||||
|
||||
google.maps.event.addListener(location_map, 'click', function(mouseEvent){
|
||||
marker.setPosition(mouseEvent.latLng);
|
||||
savePosition(mouseEvent.latLng);
|
||||
});
|
||||
|
||||
google.maps.event.addListener(location_map, 'zoom_changed', function(mouseEvent){
|
||||
savePosition(point);
|
||||
});
|
||||
|
||||
location_based.bindWithDelay("keypress", function() {
|
||||
|
||||
var lstr = [];
|
||||
location_based.each(function(){
|
||||
var b = $(this);
|
||||
lstr.push(b.val())
|
||||
});
|
||||
|
||||
geocode(lstr.join(','), function(l){
|
||||
location_coordinate.val( l.lat()+','+l.lng() );
|
||||
});
|
||||
|
||||
onLocationCoordinateChange();
|
||||
}, 2000 );
|
||||
|
||||
|
||||
function onLocationCoordinateChange()
|
||||
{
|
||||
var latlng = jQuery(this).val().split(/,/);
|
||||
if (latlng.length < 2) return;
|
||||
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());
|
||||
//});
|
||||
}
|
||||
|
||||
function placeMarker(location) {
|
||||
marker.setPosition(location);
|
||||
location_map.setCenter(location);
|
||||
savePosition(location);
|
||||
location_map.panTo(location);
|
||||
}
|
||||
|
||||
function geocode(address, cb) {
|
||||
var result;
|
||||
var geocoder = new google.maps.Geocoder();
|
||||
if (geocoder) {
|
||||
geocoder.geocode({"address": address}, function(results, status) {
|
||||
if (status == google.maps.GeocoderStatus.OK) {
|
||||
cb(results[0].geometry.location);
|
||||
placeMarker(results[0].geometry.location);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
function geocode_reverse(location, cb) {
|
||||
var geocoder = new google.maps.Geocoder();
|
||||
if (geocoder) {
|
||||
geocoder.geocode({"latLng": location}, function(results, status) {
|
||||
if (status == google.maps.GeocoderStatus.OK) {
|
||||
cb(results[0].geometry.location);
|
||||
placeMarker(results[0].geometry.location);
|
||||
}
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
placeMarker(initial_position);
|
||||
}
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
|
||||
$('input[data-location-widget]').each(function(){
|
||||
var $el = $(this);
|
||||
|
||||
var $map = $($el.attr('data-map')),
|
||||
$based_fields = $($el.attr('data-based-fields')),
|
||||
zoom = parseInt($el.attr('data-zoom'));
|
||||
|
||||
location_field_load($map, $based_fields, zoom);
|
||||
});
|
||||
});
|
||||
40
location_field/models.py
Executable file
40
location_field/models.py
Executable file
@@ -0,0 +1,40 @@
|
||||
from django.db.models import CharField
|
||||
|
||||
from location_field import forms
|
||||
|
||||
|
||||
class BaseLocationField(object):
|
||||
def __init__(self, based_fields=[], zoom=2, default=None, *args, **kwargs):
|
||||
self._based_fields = based_fields
|
||||
self._zoom = zoom
|
||||
self._default = default
|
||||
self.default = default
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
return super(BaseLocationField, self).formfield(
|
||||
form_class=self.formfield_class,
|
||||
based_fields=self._based_fields,
|
||||
zoom=self._zoom,
|
||||
default=self._default,
|
||||
**kwargs)
|
||||
|
||||
|
||||
class PlainLocationField(BaseLocationField, CharField):
|
||||
formfield_class = forms.PlainLocationField
|
||||
|
||||
def __init__(self, based_fields=None, zoom=None,
|
||||
max_length=63, *args, **kwargs):
|
||||
|
||||
super(PlainLocationField, self).__init__(based_fields=based_fields,
|
||||
zoom=zoom, *args, **kwargs)
|
||||
|
||||
CharField.__init__(self, max_length=max_length, *args, **kwargs)
|
||||
|
||||
|
||||
# south compatibility
|
||||
try:
|
||||
from south.modelsinspector import add_introspection_rules
|
||||
add_introspection_rules([], ["^location_field\.models\.LocationField"])
|
||||
add_introspection_rules([], ["^django\.contrib\.gis"])
|
||||
except:
|
||||
pass
|
||||
11
location_field/urls.py
Normal file
11
location_field/urls.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from django.conf.urls.defaults import patterns
|
||||
|
||||
import os
|
||||
|
||||
app_dir = os.path.dirname(__file__)
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
(r'^media/(.*)$', 'django.views.static.serve', {
|
||||
'document_root': '%s/media' % app_dir}),
|
||||
)
|
||||
1
location_field/views.py
Executable file
1
location_field/views.py
Executable file
@@ -0,0 +1 @@
|
||||
# Create your views here.
|
||||
54
location_field/widgets.py
Normal file
54
location_field/widgets.py
Normal file
@@ -0,0 +1,54 @@
|
||||
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
|
||||
self.zoom = zoom
|
||||
super(LocationWidget, self).__init__(attrs)
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is not None:
|
||||
lat, lng, zoom = value.split(',')
|
||||
|
||||
value = '%s,%s,%d' % (
|
||||
float(lat),
|
||||
float(lng),
|
||||
float(zoom)
|
||||
)
|
||||
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))
|
||||
|
||||
attrs = attrs or {}
|
||||
attrs['data-location-widget'] = name
|
||||
attrs['data-based-fields'] = based_fields
|
||||
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})
|
||||
|
||||
class Media:
|
||||
# Use schemaless URL so it works with both, http and https websites
|
||||
js = (
|
||||
'//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', # jquery
|
||||
'//maps.google.com/maps/api/js?sensor=false&language=de',
|
||||
'/static/js/bindWithDelay.js',
|
||||
'/location_field/media/form.js',
|
||||
)
|
||||
Reference in New Issue
Block a user