Rishi Kulshreshtha
Rishi Kulshreshtha

Reputation: 1878

Google Place Autocomplete for Postal Code

I'm trying to create an autocomplete text box that should only provide the postal code. Here is the documentation that I have followed: https://developers.google.com/places/webservice/autocomplete#place_types

JSFiddle working example is here

If I'm using the postal_code it is not working for me, but it is fine when I'm using the cities. What should I do to achieve an autocomplete with only postal codes?

function postal_code() {
  var input = document.getElementById('field-postal');
  var options = {
    types: ['(postal_code)'],
    componentRestrictions: {
      country: "in"
    }
  }
  var autocomplete = new google.maps.places.Autocomplete(input, options);
}

google.maps.event.addDomListener(window, 'load', postal_code);

Upvotes: 25

Views: 73091

Answers (6)

Ivan Li Trenta
Ivan Li Trenta

Reputation: 51

Google documentation can be a bit confusing. But I think i find the answer:

To search only by postal code:

types:['postal_code']

To search address including by postal code:

types:['(regions)']

or

types:['geocode']

See below the documentation from Google

https://developers.google.com/maps/documentation/places/web-service/autocomplete#types

You can safely mix the geocode and establishment types. You cannot mix type collections (address, (cities) or (regions)) with any other type, or an error occurs.

https://developers.google.com/maps/documentation/places/web-service/supported_types#table3

The supported types are:

  • geocode instructs the Place Autocomplete service to return only geocoding results, rather than business results. Generally, you use this request to disambiguate results where the location specified may be indeterminate.
  • address instructs the Place Autocomplete service to return only geocoding results with a precise address. Generally, you use this request when you know the user will be looking for a fully specified address.
  • establishment instructs the Place Autocomplete service to return only -business results.
  • The (regions) type collection instructs the Places service to return any result matching the following types:
    • locality
    • sublocality
    • postal_code
    • country
    • administrative_area_level_1
    • administrative_area_level_2
  • The (cities) type collection instructs the Places service to return results that match locality or administrative_area_level_3.

Upvotes: 5

Hasan Sawan
Hasan Sawan

Reputation: 421

I have created a simple solution after googling for some time. It basically returns the postcode after looping through the

address_component

function initAutocomplete() {

   var inputPostCode1 = document.getElementById('input_1_2_5');
   var options = {
        types: ['geocode']
    };
  autoPostcode1 = new google.maps.places.Autocomplete(inputPostCode1, options);
  google.maps.event.addListener(autoPostcode1, 'place_changed', function() {
    document.getElementById('input_1_2_5').value = getPostCode(autoPostcode1.getPlace());
  })

      
} // initAutocomplete

    function getPostCode(place){
        for (var i = 0; i < place.address_components.length; i++) {
            for (var j = 0; j < place.address_components[i].types.length; j++) {
              if (place.address_components[i].types[j] == "postal_code") {
                console.log(place.address_components[i]);
                return place.address_components[i].long_name;
              }
            }
          }
    }

Upvotes: 1

micah
micah

Reputation: 1218

If not using javascript use the following http request with the google api place textsearch endpoint

https://maps.googleapis.com/maps/api/place/textsearch/json?query=971&fields=formatted_address&inputtype=textquery&key=[my_key]

Upvotes: -1

glenn223
glenn223

Reputation: 303

I know this is a little old but... I thought I should share my knowledge and hope it helps someone.

@geocodezip is right, you can't specifically request Google to return only postcode results. However, you can request regions and tell the user when they've messed it all up!

This is the code I use. It uses 2 inputs; an address prefix (house name/number) and postcode

Requirements:
A div with 2 inputs (for searching).
Below that, a div container which contains inputs with the below id's: (these can be prefixed)

  • Address1
  • Address2
  • City
  • County
  • Postcode
  • Country

Each of my user inputs has the class "InputControl", so I use this in my function to clear previous values.

Using it

var autoAddr;

function initAutocomplete() {
    autoAddr = new google.maps.places.Autocomplete(document.getElementById('AddressSearchField'), { types: ['(regions)'] });
    autoAddr.addListener('place_changed', FillInAddress);
}
function FillInAddress() {
    GooglePlacesFillAddress(autoAddr, "#AddressCont", "");
}

The main function

function GooglePlacesFillAddress(Place, ContainerId, AddressPrefix) {
    var
        place = Place.getPlace(),
        arr = ['premise', 'route', 'locality', 'postal_town', 'administrative_area_level_2', 'postal_code', 'country'],
        dict = {},
        adr = $(ContainerId).find("#" + AddressPrefix + "Address1"),
        switched = false,
        switchedAgain = false,
        searchAgain = $("<p id=\"" + AddressPrefix + "AddressSearchAgain\"><a href=\"javascript:void(0)\" class=\"Under\">I would like to search again</a></p>"),
        asc = $("#" + AddressPrefix + "AddressSearchCont"),
        adressPrefixValue = $("#" + AddressPrefix + "AddressSearchPrefixField").val().trim();

    SlideShow(ContainerId),
    $(ContainerId).find("input.InputControl").val(''),
    asc.find("#" + AddressPrefix + "AddressSearchField, #" + AddressPrefix + "AddressSearchPrefixField").attr("disabled", "disabled"),
    asc.find("#" + AddressPrefix + "AddressSearchFieldButton").addClass("disabled"),
    asc.find("#" + AddressPrefix + "AddressSearchPrefixField").after(searchAgain),
    searchAgain.on("click", function () {
        $(this).remove(),
        asc.find("#" + AddressPrefix + "AddressSearchField, #" + AddressPrefix + "AddressSearchPrefixField").removeAttr("disabled").val(''),
        asc.find("#" + AddressPrefix + "AddressSearchFieldButton").removeClass("disabled"),
        asc.find("#" + AddressPrefix + "AddressSearchPrefixField").focus();
    });

    if (place.address_components && place.address_components.length)
        for (var i = 0; i < place.address_components.length; i++)
            for (var j = 0; j < place.address_components[i].types.length; j++)
                if ($.inArray(place.address_components[i].types[j], arr) >= 0)
                    dict[place.address_components[i].types[j]] = place.address_components[i]["long_name"];

    $(ContainerId).find("#" + AddressPrefix + "City").val(dict["postal_town"] || '');
    $(ContainerId).find("#" + AddressPrefix + "County").val(dict["administrative_area_level_2"] || '');
    $(ContainerId).find("#" + AddressPrefix + "Postcode").val(dict["postal_code"] || '');
    $(ContainerId).find("#" + AddressPrefix + "Country").val(dict["country"] || 'United Kingdom');

    var isPostal = false;
    if (place.types && place.types.length)
        if ($.inArray("postal_code", place.types) >= 0 && $.inArray("postal_code_prefix", place.types) < 0)
            isPostal = true;

    // Add street number
    InputAdder(adr, adressPrefixValue, true);

    // Add premise
    if (adressPrefixValue.length == 0 || adr.val().length + (dict["premise"] || '').length > 100)
        adr = $(ContainerId).find("#" + AddressPrefix + "Address2"), switched = true;
    InputAdder(adr, (dict["premise"] || ''), true);

    // Add route
    if (adr.val().length + (dict["route"] || '').length > 100) {
        adr = $(ContainerId).find("#" + AddressPrefix + (switched ? "City" : "Address2"));
        if (switched)
            switchedAgain = true;
        else
            switched = true;
    }
    InputAdder(adr, (dict["route"] || ''), !switchedAgain, adressPrefixValue.length > 0 && adr.val() == adressPrefixValue);

    // Add locality
    InputAdder(switched ? adr : $(ContainerId).find("#" + AddressPrefix + "Address2"), (dict["locality"] || ''), !switchedAgain);

    if (!isPostal)
        WriteBorderedBox(false, ContainerId, "The postcode provided doesn't appear to be complete/valid. Please confirm the below address is correct."),
        $(ContainerId).find("#" + AddressPrefix + "Address1").focus();
}

Helper functions

function InputAdder(Obj, Text, Post, DontAddComma) {
    if (Obj && Text.length > 0) {
        var
            i = Obj.val().trim() || '',
            comma = !!DontAddComma ? "" : ",";

        Obj.val(
            (Post && i.length > 0 ? i + comma + ' ' : '') +
            Text.trim() +
            (!Post && i.length > 0 ? comma + ' ' + i : ''));
    }
}
function WriteBorderedBox(outcome, identifier, text) {
    var
        box = $("<div class=\"Bordered" + (outcome ? "Success" : "Error") + "\"><p>" + text + "</p></div>");
    $(identifier).before(box);
    box.hide().slideDown(function () { $(this).delay(6000).slideUp(function () { $(this).remove(); }); });
}

If you want a button (like me)

$("#AddressSearchFieldButton").click(function (e) {
    var input = document.getElementById("AddressSearchField");

    google.maps.event.trigger(input, 'focus')
    google.maps.event.trigger(input, 'keydown', { keyCode: 40 });
    google.maps.event.trigger(input, 'keydown', { keyCode: 13 });
});

Upvotes: 1

Yergalem
Yergalem

Reputation: 1763

I used postal_code address component type.

Make sure you included the places library in your script url as:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCBbt5ueucPc0u9VQDb8wFvFigV90PpTQA&libraries=places&callback=initEditClntInfoAutoComplete"    async defer>  </script>

Working Example

https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete

////////// PART FROM MY WORKING CODE
////////// Replace getByElementId with your form input IDs

  ////  Global Vars

  var  editClntInfoAutocomplete, addrStreet ="",
       addressComponets = {
                    street_number: 'short_name',
                    route: 'long_name',
                    locality: 'long_name',
                    administrative_area_level_1: 'short_name',
                    country: 'long_name',
                    postal_code: 'short_name'
       };

function initEditClntInfoAutoComplete() {   // Callback  

      editClntInfoAutocomplete = new google.maps.places.Autocomplete(
            /** @type {!HTMLInputElement} */(document.getElementById('clntInfoEditAddr1')),
            {types: ['geocode']});

        // When the user selects an address from the dropdown, populate the address
        // fields in the form.
        editClntInfoAutocomplete.addListener('place_changed', fillInEditClntInfoAddress);
    }

    function fillInEditClntInfoAddress() {

        var place = editClntInfoAutocomplete.getPlace();        

            clearPrevEditFrmAddrVals();

        for ( var i = 0; i < place.address_components.length; i++) {

              var addressType = place.address_components[i].types[0]; 
              if (  addressComponets[addressType] ) {
                    var val = place.address_components[i][addressComponets[addressType]];                 

                    assignEditFrmAddrFieldsVal(addressType, val );
              }

         }

           if( addrStreet != "")
                 document.getElementById("clntInfoEditAddr1").value = addrStreet;

     }

     function assignEditFrmAddrFieldsVal( addressType , val ) {

            switch( addressType ) {
                case "administrative_area_level_1":
                        document.getElementById("clntInfoEditState").value = val;  break;
                case "locality":
                    document.getElementById("clntInfoEditCity").value = val;  break;
                //   case "country":
                //        document.getElementById("addressType").value = val;  break;
                case "postal_code":
                    document.getElementById("clntInfoEditZip").value = val;  break;  
                case "street_number": 
                case "route":     
                    addrStreet += " "+val;      break;

            }

     }

     function clearPrevEditFrmAddrVals(){
         var editClntFrmAddrIDs = ["clntInfoEditState","clntInfoEditCity","clntInfoEditZip","clntInfoEditAddr1"];
             addrStreet = "";

         for( var frmID in editClntFrmAddrIDs )
              wrap(editClntFrmAddrIDs[frmID]).val("");
     }

Upvotes: 2

geocodezip
geocodezip

Reputation: 161334

The documentation isn't very clear.

  • the (regions) type collection instructs the Places service to return any result matching the following types:
    • locality
    • sublocality
    • postal_code
    • country
    • administrative_area_level_1
    • administrative_area_level_2

Upvotes: 32

Related Questions