Last active
May 11, 2018 08:45
-
-
Save michaelhjulskov/17d746f287bc8f3af2a341a4efed08c8 to your computer and use it in GitHub Desktop.
django-map-widget form extension that finds restaurant from name and city field values - using google api PlacesService
This file contains 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
{% extends "mapwidgets/google-point-field-widget.html" %} | |
{% load i18n %} | |
{% block extra_javascript %} | |
$(document).ready(function() { | |
if (typeof map_widget_autofill == 'function'){ | |
map_widget_autofill(widget); | |
} | |
}); | |
{% endblock %} |
This file contains 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
... the usual form stuff | |
{% block javascript %} | |
{{ block.super }} | |
<script type="text/javascript"> | |
(function($) { | |
map_widget_autofill = function (widget) { | |
var locationInput = widget.locationInput; | |
var form = $(locationInput).closest('form'); | |
var name = form.find('#id_name'); | |
var street = form.find('#id_street'); | |
var postcode = form.find('#id_zipcode'); | |
var city = form.find('#id_city'); | |
var country = form.find('#id_country'); | |
var phone_number = form.find('#id_phone_number'); | |
var onload_country = {% if country %}'{{ country }}'{% else %}false{% endif %}; | |
var onload_language = {% if language %}'{{ language }}'{% else %}false{% endif %}; | |
// if the location input isn't set, try to fetch GPS coordinates at document load | |
if (!locationInput.val()) { | |
$(widget.addressAutoCompleteInput).attr("placeholder", "{% trans 'Enter address here' %}"); | |
{% if center_here %} | |
widget.map.setCenter({ lat: {{ center_here.y|safe }}, lng: {{ center_here.x|safe }} }); | |
widget.map.setZoom(10); | |
{% endif %} | |
update_map(); | |
} | |
// update every time the text inputs change | |
$([name, street, postcode, city, country]).each(function() { | |
$(this).change(function() { | |
update_map(); | |
}); | |
}); | |
$(document).on("google_point_map_widget:place_changed", function (e, place, lat, lng, locationInputElem, mapWrapID) { | |
console.log(place); | |
offerToInsertValues(place); | |
//insertValues(place); | |
}); | |
function offerToInsertValues(place) { | |
console.log('offerToInsertValues'); | |
if (place.address_components){ | |
if ("street_address" in place.types){ | |
// its a street address object - lets try and see if there is a restaurant on that specific location | |
places_service = new google.maps.places.PlacesService(widget.map); | |
places_service.nearbySearch({location: place.geometry.location, radius: '50', type: ['restaurant'], rankby: 'distance'}, function(result, status) { // keyword - name | |
if (status !== google.maps.places.PlacesServiceStatus.OK) { | |
console.error(status); | |
insertValues(place); | |
return; | |
} | |
console.log(result); | |
insertValues(result); | |
return; | |
}); | |
} else { | |
insertValues(place); | |
} | |
} else { | |
places_service = new google.maps.places.PlacesService(widget.map); | |
places_service.getDetails({ | |
placeId: place.place_id | |
}, function(result, status) { | |
if (status !== google.maps.places.PlacesServiceStatus.OK) { | |
console.error(status); | |
return; | |
} | |
console.log(result); | |
insertValues(result); | |
return; | |
}); | |
} | |
} | |
function insertValues(place) { | |
console.log('insertValues'); | |
address_suggestion = false; | |
street_and_number = false; | |
postal_code = false; | |
locality = false; | |
country = false; | |
if (place.address_components){ | |
street_number = getAddressComponents(place.address_components, 'street_number'); | |
route = getAddressComponents(place.address_components, 'route'); | |
postal_code = getAddressComponents(place.address_components, 'postal_code'); | |
locality = getAddressComponents(place.address_components, 'locality'); | |
country = getAddressComponents(place.address_components, 'country'); | |
if (route && street_number){street_and_number = route.long_name + " " + street_number.long_name;} else if (route){street_and_number = route.long_name;} else {street_and_number = '';} | |
if (place.formatted_address){ | |
address_suggestion = '\n' + place.formatted_address; | |
} else { | |
address_suggestion = street_and_number; | |
if (postal_code){address_suggestion += '\n' + postal_code.long_name;} | |
if (locality){address_suggestion += '\n' + locality.long_name;} | |
if (country){address_suggestion += '\n' + country.long_name;} | |
} | |
} | |
if (place.formatted_phone_number){address_suggestion += '\n' + place.formatted_phone_number;} | |
if (place.website){address_suggestion += '\n' + place.website;} | |
if (address_suggestion && confirm('{% trans "I found these informations. Want to use them?" %}'+'\n'+address_suggestion)){ | |
if (street_and_number && !street.val()){street.val(street_and_number);} | |
if (postal_code && !postcode.val()){postcode.val(postal_code.long_name);} | |
if (locality && !city.val()){city.val(locality.long_name);} | |
if (country){$('#id_country option[value="' + country.short_name + '"]').prop('selected', true);} | |
if (place.international_phone_number && !phone_number.val()){phone_number.val(place.international_phone_number.replace(/\s+/g, ''));} | |
if (place.website && !$("#id_website").val()){$('#id_website').val(place.website);} | |
if (place.place_id && !("street_address" in place.types)){$('#id_google_place_id').val(place.place_id);} | |
if (place.opening_hours){ | |
//console.log('periods:'+place.opening_hours.periods); | |
for(var i=0; i<place.opening_hours.periods.length; i++) { | |
period = place.opening_hours.periods[i]; | |
daynum = period.open.day; | |
// hours format: 00:00 | |
// select id format: id_day1_1-opens & id_day1_1-shuts (1 to 7) | |
if (daynum == 0){daynum=7;} | |
$('#div_id_openinghours .set1 select#id_day'+String(daynum)+'_1-opens option[value="' + pad(period.open.hours, 2) + ':' + pad(period.open.minutes, 2) + '"]').prop('selected', true); | |
$('#div_id_openinghours .set1 select#id_day'+String(daynum)+'_1-shuts option[value="' + pad(period.close.hours, 2) + ':' + pad(period.close.minutes, 2) + '"]').prop('selected', true); | |
} | |
} /* else { | |
$('#div_id_openinghours .set1 select[id*="id_day"] option[value="00:00"]').prop('selected', true); | |
} */ | |
} | |
} | |
function pad(num, size) { | |
var s = "000000000" + num; | |
return s.substr(s.length-size); | |
} | |
//gets "street_number", "route", "locality", "country", "postal_code" | |
function getAddressComponents(components, type) { | |
for (var key in components) { | |
if (components.hasOwnProperty(key)) { | |
if (type == components[key].types[0]) { | |
return components[key]; | |
} | |
} | |
} | |
return false; | |
} | |
function addMarker(place){ | |
var geo_location = place.geometry.location; | |
var latitude = geo_location.lat(); | |
var longitude = geo_location.lng(); | |
// add marker to map | |
widget.addMarkerToMap(latitude, longitude); | |
widget.updateLocationInput(latitude, longitude); | |
// set center position (or fit bounds) | |
widget.map.setCenter(geo_location); | |
// widget.fitBoundMarker(); | |
// set zoom (change according your needs or use bounds if you wish) | |
widget.map.setZoom(18); | |
} | |
function update_map() { | |
if (!locationInput.val()) { | |
if (street.val() && postcode.val() && city.val() && country.val()){ | |
// join all address parts values into single string | |
var address = street.val() + ', ' + postcode.val() + ' ' + city.val() + ', ' + country.val(); | |
// initialize autocomplete service API | |
var autocomplete_service = new google.maps.places.AutocompleteService(); | |
// try to find address prediction using autocomplete service API | |
autocomplete_service.getPlacePredictions({input: address}, function (predictions, status) { | |
// if status is incorrect, clear search value | |
if (status == google.maps.places.PlacesServiceStatus.OK) { | |
if (predictions.length >= 1) { | |
// otherwise if there is at least 1 prediction available, pick the very first one | |
var address_by_prediction = predictions[0].description; | |
// set the address as search value | |
$(widget.addressAutoCompleteInput).val(address_by_prediction); | |
// try to find the GPS coordinates of the predicted address | |
widget.geocoder.geocode({'address' : address_by_prediction}, function(results, status) { | |
if (status === google.maps.GeocoderStatus.OK) { | |
if (results.length == 1){ | |
offerToInsertValues(results[0]) | |
addMarker(results[0]); | |
} else { | |
console.log('more than one match:'); console.log(results); | |
widget.map.setCenter(results[0].geometry.location); | |
widget.map.setZoom(15); | |
} | |
} | |
}); | |
} | |
} | |
}); | |
} else if (name.val() && city.val() && country.val()){ | |
var name_and_city = name.val().trim() + " " + city.val().trim(); | |
$(widget.addressAutoCompleteInput).val(name_and_city); | |
places_service = new google.maps.places.PlacesService(widget.map); | |
places_service.textSearch({ query: name_and_city + " " + country.val() }, function(results, status) { | |
if (status == google.maps.places.PlacesServiceStatus.OK) { | |
if (results.length == 1){ | |
offerToInsertValues(results[0]) | |
addMarker(results[0]); | |
} else { | |
console.log('more than one match:'); console.log(results); | |
widget.map.setCenter(results[0].geometry.location); | |
widget.map.setZoom(15); | |
} | |
} | |
}); | |
} | |
} | |
} | |
} | |
})(jQuery || django.jQuery); | |
</script> | |
{% endblock javascript %} |
This file contains 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
# simplified.... | |
def SignupView(request): | |
language = to_locale(get_language()) | |
initial = {'language': language} | |
center_here = country = False | |
ip = get_client_ip(request) | |
if ip: | |
g = GeoIP() | |
c = g.city(ip) | |
if c: | |
if c['latitude'] and c['longitude']: | |
center_here = Point(c['longitude'], c['latitude']) | |
if c['country_code']: | |
country = c['country_code'] | |
initial['country'] = country | |
form = RegisterForm(request.POST or None, request.FILES or None, initial=initial) | |
if request.method == 'POST': | |
if form.is_valid(): | |
form.save() | |
messages.success(request, _("Welcome!")) | |
return redirect('settings') | |
else: | |
messages.error(request, _("Please correct the error below.")) | |
if form.cleaned_data.get('location'): | |
center_here = False | |
return render(request, 'signup.html', { | |
'form': form, | |
'center_here': center_here, | |
'country': country, | |
'language': language, | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
working on the signup form here:
https://pizzamain.me/
Feel free to play around with it Erik
another thing! Language!
I've tried to set map language dynamically onload, but failed.
I dont know, maybe this can help:
http://googlemaps.github.io/js-samples/map_language/map_lang.html