1
votes

What I have at the moment is a place autocomplete which displays results for one country. What I want to do is make it display results for more countries (limited to 2 or 3).

As I understand it, this is not possible with the current version of the autocomplete ( https://code.google.com/p/gmaps-api-issues/issues/detail?id=4233) So what I'm going to do is get two lists of predictions and display those instead of the autocomplete result.

Is there any way to trigger the dropdown part of the autocomplete and populate it with the predictionslist?

triggered code in the onChange of the input:

var inputData  = this.value;
var options = {
        componentRestrictions: { country: "be" }
};
service = new google.maps.places.AutocompleteService();
var request = {
    input: inputData,
    componentRestrictions: {country: 'be'},
};
var secondaryRequest = {
    input: inputData,
    componentRestrictions: {country: 'lu'},
};
service.getPlacePredictions(request, callback);
service.getPlacePredictions(secondaryRequest, callback);

callback function:

function callback(predictions, status) {
  if (status != google.maps.places.PlacesServiceStatus.OK) {
    alert(status);
    return;
  }  
    //here I need to display that dropdown if it isn't already
    // and then add the results of the current predictions.
}

UPDATE

Multiple countries filter in place autocomplete was introduced in version 3.27 of Maps JavaScript API in January 2017:

You can now restrict Autocomplete predictions to only surface from multiple countries. You can do this by specifying up to 5 countries in the componentRestrictions field of the AutocompleteOptions.

source: https://developers.google.com/maps/documentation/javascript/releases#327

1
So I made a workaround for this using the above code and a custom 'pop up' div to show the result. I'll leave the question open for a few days in case anyone has a better idea. after that I'll post my solution (since it needs some cleaning up). - Ruben Verschueren

1 Answers

1
votes

Here's my demo solution. As mentioned in the comment. it uses several calls to get predictions and build up the result list with them. When a result is selected the address is geocoded. This means 3 calls instead of 1 with the autocomplete, but so far I haven't found a way around it.

<!DOCTYPE html>
    <html>
    <head>
    <title>Retrieving Autocomplete Predictions</title>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=places&v=3.exp"></script>
    <script>

    function initialize() {  
       $("#place").live("keyup", function (evt) {           
            // Clear any previously set timer before setting a new one
            window.clearTimeout($(this).data("timeout"));
            $(this).data("timeout", setTimeout(function () {
                //whe the timeout has expired get the predictions
                var inputData = $("#place").val();          
                service = new google.maps.places.AutocompleteService();
                var request = {
                    input: inputData,
                    componentRestrictions: {country: 'be'},
                };
                var secondaryRequest = {
                    input: inputData,
                    componentRestrictions: {country: 'lu'},
                };
                $('#resultWindow').empty();
                service.getPlacePredictions(request, callback);
                service.getPlacePredictions(secondaryRequest, callback);            
            }, 1000));
        });

        function callback(predictions, status) {
            if (status != google.maps.places.PlacesServiceStatus.OK) {
                console.log(status);
                return;
            }    
            var resultHTML = '';
            for (var i = 0, prediction; prediction = predictions[i]; i++) {
                resultHTML += '<div>' + prediction.description + '</div>';
            }
            if($('#resultWindow').html() != undefined && $('#resultWindow').html() != ''){      
                resultHTML = $('#resultWindow').html()+ resultHTML;
            }       
            if(resultHTML != undefined && resultHTML != ''){        
                $('#resultWindow').html(resultHTML).show();
            }
            //add the "powered by google" image at the bottom -> required!!
            if($('#resultWindow').html() != undefined){
                $('#resultWindow #googleImage').remove();
                var imageHtml = $('#resultWindow').html() + '<img id="googleImage" src="powered-by-google-on-white2.png"/>';
                $('#resultWindow').html(imageHtml);
            }
        }

        function geocodeAddress(address) {      
            var geocoder = new google.maps.Geocoder();      
            geocoder.geocode({'address': address}, function (results, status) 
            {   
              if (status == google.maps.GeocoderStatus.OK) 
              {
                $('#latitude').val(results[0].geometry.location.lat());
                $('#longitude').val(results[0].geometry.location.lng());        
              }
              else {
                console.log("Error: " + google.maps.GeocoderStatus);
              }
            });
        }
        $('#resultWindow div').live('click',function(){
            //get the coördinates for the selected (clicked) address
            $('#resultWindow').hide();
            var address = $(this).text();
            var addressParts = address.split(',');
            $('#country').val(addressParts[2]);
            $('#city').val(addressParts[1]);
            $('#place').val(addressParts[0]);
            if(address != ''){
                geocodeAddress(address);
            }
        });
      /*end custom autocomplete stuff*/
    }
    google.maps.event.addDomListener(window, 'load', initialize);

    </script>
    <style type="text/css">
    #resultWindow{  
        position: fixed;
       /* top: 0;
        left: 0;
        width: 100%;
        height: 100%;*/
        background-color: #fff;
        filter:alpha(opacity=50);
        -moz-opacity:0.5;
        -khtml-opacity: 0.5;
        opacity: 0.5;
        z-index: 10000;
        border: 1px solid black;
        color:black;
        display:none;
    }
    </style>
    </head>
<body>
<div id="placeholder">  
    <input type="text" id="place" style="width:200px;"/>
    <label for="latitude">Latitude</label>
    <input type="text" id="latitude"/>
    <label for="longitude">Longitude</label>
    <input type="text" id="longitude"/>
    <label for="city">city</label>
    <input type="text" id="city"/>
    <label for="country">selected country</label>
    <input type="text" id="country"/>
    <div id="resultWindow"></div>   
</div>
</body>
</html>