1

I'm using google map API V3 with places and autocomplete API and I have a problem with event order.

I have an input text and when I enter an address in this field I have the autocomplete then I can choose the address with my mouse. It works perfectly.

But if the user type the address without choose the address inside the autocomplete suggestion, the place_changedisn't triggered and I can't get the google map object to split the address in the different part (postal_code, city, street_numer...).

So I thought about a solution. I decided to use the blur event. In this event I'll use the geocoder to retrieve the address if the user type an ambiguous address or if the user doesn't have click on the autocomplete suggestions. Then I can get the postal_code, street_number... Even the use type an ambiguous address.

I want to use the blur event only if the user doesn't click on the autocomplete suggestion. But the problem is that the blur event is trigged before the google map autocomplete event then I can't set a flag variable.

I have to do that because when I'm choosing an address inside the autocomplete suggestion the blur event is triggered and sometimes I have the address of the suggestion and sometimes I have the result of the geocoder.

Here is a part of my code :

autocomplete = new google.maps.places.Autocomplete(input, options);

google.maps.event.addListener(autocomplete, 'place_changed', function() {

    var place = autocomplete.getPlace();

    initializeAddress(place);
});

function geocoder(ambiguousAddress){
    var geocoder = new google.maps.Geocoder();

    geocoder.geocode({"address": ambiguousAddress}, function(results, status) {

        if (status == google.maps.GeocoderStatus.OK) {
            $('#address').val(results[0].formatted_address);
            initializeAddress(results[0]);
        }
    });
}

function initializeAddress(place){
    for (var i = 0; i < place.address_components.length; i++) {
        var addressType = place.address_components[i].types[0];

        latitude = place.geometry.location.lat();
        longitude = place.geometry.location.lng();

        switch (addressType) {
            case 'street_number':
                street_number = place.address_components[i][componentForm[addressType]];
                break;
            case 'route':
                route = place.address_components[i][componentForm[addressType]];
                break;
            case 'locality':
                city = place.address_components[i][componentForm[addressType]];
                break;
            case 'postal_code':
                postal_code = place.address_components[i][componentForm[addressType]];
                break;
            default:
                break;
        }
    }

    address = street_number + ' ' + route;
}

$('#address').on('blur', function(e) {
    if( $.trim($(this).val()) != '' ){
        geocoder($(this).val());
    }
});
John
  • 4,711
  • 9
  • 51
  • 101

3 Answers3

2

Ran into a similar issue. As per the API v3 documentation, if the user doesn't select anything from the dropdown, getPlace returns a stub with only the input value as place.name. Geocoding place.name if address components are undefined solves a number of scenarios except for tabbing out. For that, I used the solution from this answer: Google Autocomplete Places API not triggering event on change via TAB.

IMHO, this seems harder than it ought to be.

function onPlaceChange() {

    console.log("on place change");
    var place = autocomplete.getPlace();
    if (typeof place.address_components !== "undefined") {
        console.log("place filled in");
        fillInAddress(place);
    } else {
        var geocoder = new google.maps.Geocoder();
        var onSuccess = function (google_results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                fillInAddress(google_results[0]);
            }
        }
        console.log("geocoding " + place.name);
        geocoder.geocode({'address': place.name}, onSuccess);
    }

}

function initAutocomplete() {

    var location_field = document.getElementById('address');
    google.maps.event.addDomListener(location_field, 'blur', function () {
        google.maps.event.trigger(this, 'focus');
        google.maps.event.trigger(this, 'keydown', {
            keyCode: 13
        });
    })

    autocomplete = new google.maps.places.Autocomplete(
        /** @type {!HTMLInputElement} */(location_field),
        {types: ['address']});

    autocomplete.addListener('place_changed', onPlaceChange);
}
Community
  • 1
  • 1
user1867622
  • 83
  • 10
0

You can find a solution here: https://stackoverflow.com/a/42101702/2409212

Basically what it does it to check if there is a pac-item (the class name for every result row) element hovered. If no element is hovered, means that the autoselect should be performed, otherwise, it will let us pick one!

Israel Ortuño
  • 1,084
  • 2
  • 14
  • 33
-1

Autocomplete class is bound to the textbox. If this is the case, I believe it already has a blur implementation (which is why its being triggered).

Check if you can register blur on the Autocomplete's listener. Hopefully this would solve the issue.

Happy coding!

adjuremods
  • 2,938
  • 2
  • 12
  • 17