Skip to content

Instantly share code, notes, and snippets.

@michaelhjulskov
Last active May 11, 2018 08:45
Show Gist options
  • Save michaelhjulskov/17d746f287bc8f3af2a341a4efed08c8 to your computer and use it in GitHub Desktop.
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
{% 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 %}
... 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 %}
# 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,
})
@michaelhjulskov
Copy link
Author

michaelhjulskov commented Apr 5, 2018

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment