Search code examples
jquerygoogle-mapsgoogle-maps-api-3google-geocodergoogle-places

Generating array of dynamics input with Google maps suggestion and focusout geocode


I am developing a script that you can add several destinations and the inputs are dynamically generated with jquery and to each input its add the google place suggestion. So when the user write a city and the event Focus Out happen automatically try to geocode the city. Everything its working well on this part the problem is when the user just write the part of name of the city and press the suggestion with the mouse, generating event of focus out before the name of the city be fully written.

Example: i am searching for "Porto, Portugal" and i just need to write "Po" for the google-suggestion suggest me "Porto, Portugal" but the problem is that pressing with mouse out he just send "Po" to google-geocode retrieving different result "Pau, France".

Searching

The result of just capture "Po" The result

And this is the code that i am using:

<!DOCTYPE html>
<html>
<head>
<title>Add or Remove text boxes with jQuery</title>
<script type="text/javascript" src="//code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3&libraries=places&language=en"></script>
<script type="text/javascript">
window.onload = function () {
    var input = /** @type {HTMLInputElement} */(document.getElementById('box1'));
    var autocomplete = new google.maps.places.Autocomplete(input,{types: ['geocode']});
}

$(window).load(function() {
    //check if the user FocusOut if yes start looking for geocoding
    $(document).on('focusout','.autocomplete',function() {
        LocationValidator(this.value);
    });
});
</script>


<style type="text/css">
<!--
#main {
    max-width: 800px;
    margin: 0 auto;
}
.autocomplete{
    width:280px;    
}
-->
</style>
</head>
<body>

<div id="main">
    <h1>Add or Remove text boxes with jQuery</h1>
    <div class="my-form">
        <form role="form" method="post" id="sendDestiny" action="mapAddSave.php">
            <p class="text-box">
                <label for="box1">Destiny <span class="box-number">1</span></label>
                <input class="autocomplete" type="text" name="boxes[]" value="" id="box1" onkeydown="if (event.keyCode == 13) return false;" />
                <a class="add-box" href="#">Add More</a>
            </p>
            <p><input type="submit" value="Submit" /></p>
        </form>
    </div>
</div>


<script type="text/javascript">
jQuery(document).ready(function($){
    //Add extra box
    $('.my-form .add-box').click(function(){
        var n = $('.text-box').length + 1;
        if( 5 < n ) {
            alert('You have reached the maximum!');
            return false;
        }
        var box_html = $('<p class="text-box"><label for="box' + n + '">Destiny <span class="box-number">' + n + '</span></label> <input class="autocomplete" type="text" name="boxes[]" value="" id="box' + n + '" onkeydown="if (event.keyCode == 13) return false;" /> <a href="#" class="remove-box">Remove</a></p>');
        box_html.hide();
        $('.my-form p.text-box:last').after(box_html);
        box_html.fadeIn('slow');


        var acInputs = document.getElementsByClassName("autocomplete");
        for (var i = 0; i < acInputs.length; i++) {
            var autocomplete = new google.maps.places.Autocomplete(acInputs[i],{types: ['geocode']});
        }
        return false;
    });
    //Remove one existing box
    $('.my-form').on('click', '.remove-box', function(){
        $(this).parent().css( 'background-color', '#FF6C6C' );
        $(this).parent().fadeOut("slow", function() {
            $(this).remove();
            $('.box-number').each(function(index){
                $(this).text( index + 1 );
            });
        });
        return false;
    });
});



function LocationValidator(value) {
    var address = "";
    var geocoder = new google.maps.Geocoder();

    geocoder.geocode({ 'address': value }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var latitude = results[0].geometry.location.lat();
            var longitude = results[0].geometry.location.lng();
            address = results[0].formatted_address;

            // iterate through address_component array and Get City and Country
            var arrAddress = results[0].address_components; itemLocality=""; itemCountry="";
            $.each(arrAddress, function (i, address_component) {
                if (address_component.types[0] == "locality"){
                    itemLocality = address_component.long_name;
                }
                if (address_component.types[0] == "country"){ 
                    itemCountry = address_component.long_name;
                }
            });
            NextFunction(latitude,longitude,itemLocality,itemCountry);
        } else {
            //call function telling that happen erro
        }
    });
}

function NextFunction(latitude,longitude,itemLocality,itemCountry)
{
  //do your next thing here....
  alert("nextFunction: "+latitude+" "+longitude+" city:"+itemLocality+" Country:"+itemCountry);
}
</script>
</body>
</html>

jsfiddle working exemple

Anyone have some suggestion how to fix this? Already try to use the event focusout and blur

thanks in advance!!!


Solution

  • Based on the comments of MrUpsidown and ztan to used place_changed i have made the next code:

    google.maps.event.addListener(autocomplete, 'place_changed', function(){
        var place = autocomplete.getPlace();
        LocationValidator(place.formatted_address);
    });
    

    i have used formatted_address for better results since place.name generate ambiguous results.

    Documentation about details of results