Place Autocomplete Address Form

  • This sample demonstrates how to use the Places Autocomplete widget to help users fill out address forms by selecting an address from a dropdown list.

  • The selected address information is then used to automatically populate the form fields, enhancing the user experience.

  • The sample code utilizes the address_components field to retrieve address details, and developers should carefully select the necessary fields to optimize billing costs.

  • It is important to note that address formats vary globally, so the components used might require adjustments to fit the specific location of your application's users, for example using postal_town for the UK and Sweden instead of locality.

  • Developers can view and run the sample using provided resources like JSFiddle, Google Cloud Shell, or cloning the sample code for local execution with Git and Node.js.

Does your application include an address form, such as the shipping address for an online order, a credit card billing address, or a ridesharing booking form? Autocomplete can help users supply the details.

The Place Autocomplete Address Form sample captures selected address components from the Google Places database, and uses them to populate an address form.

Since this sample only requires a place address in a structured format, the sample code uses just one place data field: addressComponents. The requested place data fields affect the cost of each request. Specify which place data fields to return in your place.fetchFields() call.

The address components in this sample are based on a typical address format. Note that you might need to use a different set of components to align with the postal address formats used in some regions. For example, the sample code selects the locality component, which often represents the city part of the address. Examples of how components can differ include:

  • In the UK and in Sweden, the component to display the city is postal_town.
  • In Japan, components differ across prefectures.
  • Brooklyn and other parts of New York City don't include the city as part of the address. Instead, they use sublocality_level_1.

When the user selects an address from the pick list, your application can populate the address form.

For more information, see Places Autocomplete widget.

If you need to validate addresses, a full-featured address validation API is available. See Address Validation in the Maps JavaScript API.

TypeScript

// This sample uses the Places Autocomplete widget to:
// 1. Help the user select a place
// 2. Retrieve the address components associated with that place
// 3. Populate the form fields with those address components.
// This sample requires the Places library, Maps JavaScript API.

let placeAutocomplete;
let address1Field: HTMLInputElement;
let address2Field: HTMLInputElement;
let postalField: HTMLInputElement;

async function initAutocomplete() {
  const { Place, Autocomplete } = (await google.maps.importLibrary(
    'places'
  )) as google.maps.PlacesLibrary;

  placeAutocomplete = document.querySelector(
    'gmp-place-autocomplete'
  ) as google.maps.places.PlaceAutocompleteElement;
  address1Field = document.querySelector('#address1') as HTMLInputElement;
  address2Field = document.querySelector('#address2') as HTMLInputElement;
  postalField = document.querySelector('#postcode') as HTMLInputElement;
  const saveButton = document.querySelector('.my-button') as HTMLButtonElement;

  placeAutocomplete.focus();

  // Handle user selection on the autocomplete widget.
  placeAutocomplete.addEventListener(
    'gmp-select',
    async ({ placePrediction }) => {
      fillInAddress(placePrediction);
    }
  );

  saveButton.addEventListener('click', () => {
    // Display a message when the Save button is clicked.
    alert('In a real application, this would save the address details.');
  });
}

async function fillInAddress(placePrediction) {
  // The placePrediction object does not have all the details needed
  // for the form, so we'll call fetchFields to get the place details.
  const { Place } = (await google.maps.importLibrary(
    'places'
  )) as google.maps.PlacesLibrary;
  const place = placePrediction.toPlace();
  await place.fetchFields({ fields: ['addressComponents'] });

  let address1 = '';
  let postcode = '';

  if (!place.addressComponents) {
    return;
  }

  // Populate form fields with address component data.
  // The field is only updated if the types array includes
  // the specified type-value.
  for (const component of place.addressComponents) {
    if (component.types.includes('street_address')) {
      address1 = `${component.longText} ${address1}`;
    }

    if (component.types.includes('street_number')) {
      address1 = `${component.longText} ${address1}`;
    }

    if (component.types.includes('route')) {
      address1 += component.shortText;
    }

    if (component.types.includes('postal_code')) {
      postcode = `${component.longText}${postcode}`;
    }

    if (component.types.includes('postal_code_suffix')) {
      postcode = `${postcode}-${component.longText}`;
    }

    if (component.types.includes('locality')) {
      (document.querySelector('#locality') as HTMLInputElement).value =
        component.longText!;
    }

    if (component.types.includes('administrative_area_level_1')) {
      (document.querySelector('#state') as HTMLInputElement).value =
        component.shortText!;
    }

    if (component.types.includes('country')) {
      (document.querySelector('#country') as HTMLInputElement).value =
        component.longText!;
    }
  }

  address1Field.value = address1;
  postalField.value = postcode;

  // After filling the form with address components from the Autocomplete
  // prediction, set cursor focus on the second address line to encourage
  // entry of subpremise information such as apartment, unit, or floor number.
  address2Field.focus();
}

initAutocomplete();

JavaScript

// This sample uses the Places Autocomplete widget to:
// 1. Help the user select a place
// 2. Retrieve the address components associated with that place
// 3. Populate the form fields with those address components.
// This sample requires the Places library, Maps JavaScript API.
let placeAutocomplete;
let address1Field;
let address2Field;
let postalField;
async function initAutocomplete() {
    const { Place, Autocomplete } = (await google.maps.importLibrary('places'));
    placeAutocomplete = document.querySelector('gmp-place-autocomplete');
    address1Field = document.querySelector('#address1');
    address2Field = document.querySelector('#address2');
    postalField = document.querySelector('#postcode');
    const saveButton = document.querySelector('.my-button');
    placeAutocomplete.focus();
    // Handle user selection on the autocomplete widget.
    placeAutocomplete.addEventListener('gmp-select', async ({ placePrediction }) => {
        fillInAddress(placePrediction);
    });
    saveButton.addEventListener('click', () => {
        // Display a message when the Save button is clicked.
        alert('In a real application, this would save the address details.');
    });
}
async function fillInAddress(placePrediction) {
    // The placePrediction object does not have all the details needed
    // for the form, so we'll call fetchFields to get the place details.
    const { Place } = (await google.maps.importLibrary('places'));
    const place = placePrediction.toPlace();
    await place.fetchFields({ fields: ['addressComponents'] });
    let address1 = '';
    let postcode = '';
    if (!place.addressComponents) {
        return;
    }
    // Populate form fields with address component data.
    // The field is only updated if the types array includes
    // the specified type-value.
    for (const component of place.addressComponents) {
        if (component.types.includes('street_address')) {
            address1 = `${component.longText} ${address1}`;
        }
        if (component.types.includes('street_number')) {
            address1 = `${component.longText} ${address1}`;
        }
        if (component.types.includes('route')) {
            address1 += component.shortText;
        }
        if (component.types.includes('postal_code')) {
            postcode = `${component.longText}${postcode}`;
        }
        if (component.types.includes('postal_code_suffix')) {
            postcode = `${postcode}-${component.longText}`;
        }
        if (component.types.includes('locality')) {
            document.querySelector('#locality').value =
                component.longText;
        }
        if (component.types.includes('administrative_area_level_1')) {
            document.querySelector('#state').value =
                component.shortText;
        }
        if (component.types.includes('country')) {
            document.querySelector('#country').value =
                component.longText;
        }
    }
    address1Field.value = address1;
    postalField.value = postcode;
    // After filling the form with address components from the Autocomplete
    // prediction, set cursor focus on the second address line to encourage
    // entry of subpremise information such as apartment, unit, or floor number.
    address2Field.focus();
}
initAutocomplete();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  font-size: 18px;
  color: rgb(104, 104, 104);
}

form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  max-width: 400px;
  padding: 20px;
  margin: 5px;
  border: 2px solid #adacac;
  border-radius: 5px;
}

input {
  width: 100%;
  margin-top: 0;
  padding: 0.5em;
  border: 0;
  border-bottom: 2px solid gray;
  font-family: 'Roboto', sans-serif;
  font-size: 18px;
}

input[type='reset'] {
  width: auto;
  height: auto;
  border-bottom: 0;
  background-color: transparent;
  color: rgb(104, 104, 104);
  font-size: 14px;
  margin: 20px 20px 0 0;
  cursor: pointer;
}

.title {
  width: 100%;
  margin-block-end: 0;
  font-weight: 500;
  margin: 0;
}

.note {
  width: 100%;
  margin-block-start: 0;
  font-size: 12px;
}

.form-label {
  width: 100%;
  padding: 0.5em;
}

.full-field {
  flex: 400px;
  margin: 15px 15px 0 0;
}

.address-row {
  display: flex;
  width: 95%;
  gap: 1.5em; /* Add space between the two fields */
  padding-bottom: 0;
}

.slim-field-left {
  flex-grow: 1;
  margin: 15px 0;
}

.slim-field-right {
  flex-grow: 1;
  margin: 15px 0;
}

.my-button {
  background-color: #000;
  border-radius: 6px;
  color: #fff;
  margin-top: 20px;
  cursor: pointer;
  padding: 6px 24px;
  text-decoration: none;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Address Form</title>

    <link
      href="https://fonts.googleapis.com/css?family=Roboto:400,500"
      rel="stylesheet" />

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </head>
  <body>
    <!-- Note: The address components in this sample are based on North American address format.
     You might need to adjust them for the locations relevant to your app. For more information, see
     https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform
    -->

    <form id="address-form" action="" method="get" autocomplete="off">
      <p class="title">Sample address form for North America</p>
      <p class="note"><em>* = required field</em></p>
      <label class="full-field">
        <span class="form-label">Deliver to*</span>
        <gmp-place-autocomplete
          included-primary-types="street_address"
          included-region-codes="US"></gmp-place-autocomplete>
      </label>
      <label class="full-field">
        <span class="form-label">Street address*</span>
        <input id="address1" name="address1" />
      </label>
      <label class="full-field">
        <span class="form-label">Apartment, unit, suite, or floor #</span>
        <input id="address2" name="address2" />
      </label>
      <label class="full-field">
        <span class="form-label">City*</span>
        <input id="locality" name="locality" required />
      </label>
      <div class="address-row">
        <label class="slim-field-left">
          <span class="form-label">State/Province*</span>
          <input id="state" name="state" required />
        </label>
        <label class="slim-field-right">
          <span class="form-label">Postal code*</span>
          <input id="postcode" name="postcode" required />
        </label>
      </div>
      <label class="full-field">
        <span class="form-label">Country/Region*</span>
        <input id="country" name="country" required />
      </label>
      <button type="button" class="my-button">Save address</button>

      <!-- Reset button provided for development testing convenience.
  Not recommended for user-facing forms due to risk of mis-click when aiming for Submit button. -->
      <input type="reset" value="Clear form" />
    </form>
  </body>
</html>

Try Sample

Clone Sample

Git and Node.js are required to run this sample locally. Follow these instructions to install Node.js and NPM. The following commands clone, install dependencies and start the sample application.

  git clone https://github.com/googlemaps-samples/js-api-samples.git
  cd samples/places-autocomplete-addressform
  npm i
  npm start