diff --git a/dist/index.html b/dist/index.html index f3a51451..c4620390 100644 --- a/dist/index.html +++ b/dist/index.html @@ -69,6 +69,7 @@

Maps JSAPI Samples

  • place-class
  • place-nearby-search
  • place-text-search
  • +
  • places-autocomplete-addressform
  • react-ui-kit-place-details
  • react-ui-kit-place-details-compact
  • react-ui-kit-place-details-latlng
  • diff --git a/dist/samples/places-autocomplete-addressform/app/.eslintsrc.json b/dist/samples/places-autocomplete-addressform/app/.eslintsrc.json new file mode 100644 index 00000000..4c44dab0 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/.eslintsrc.json @@ -0,0 +1,13 @@ +{ + "extends": [ + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "rules": { + "@typescript-eslint/ban-ts-comment": 0, + "@typescript-eslint/no-this-alias": 1, + "@typescript-eslint/no-empty-function": 1, + "@typescript-eslint/explicit-module-boundary-types": 1, + "@typescript-eslint/no-unused-vars": 1 + } +} diff --git a/dist/samples/places-autocomplete-addressform/app/README.md b/dist/samples/places-autocomplete-addressform/app/README.md new file mode 100644 index 00000000..453fa53e --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/README.md @@ -0,0 +1,40 @@ +# Google Maps JavaScript Sample + +This sample is generated from @googlemaps/js-samples located at +https://github.com/googlemaps-samples/js-api-samples. + +## Setup + +### Before starting run: + +`npm i` + +### Run an example on a local web server + +`cd samples/places-autocomplete-addressform` +`npm start` + +### Build an individual example + +`cd samples/places-autocomplete-addressform` +`npm run build` + +From 'samples': + +`npm run build --workspace=places-autocomplete-addressform/` + +### Build all of the examples. + +From 'samples': + +`npm run build-all` + +### Run lint to check for problems + +`cd samples/places-autocomplete-addressform` +`npx eslint index.ts` + +## Feedback + +For feedback related to this sample, please open a new issue on +[GitHub](https://github.com/googlemaps-samples/js-api-samples/issues). diff --git a/dist/samples/places-autocomplete-addressform/app/index.html b/dist/samples/places-autocomplete-addressform/app/index.html new file mode 100644 index 00000000..e0c88b97 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/index.html @@ -0,0 +1,71 @@ + + + + + + Place Autocomplete Address Form + + + + + + + + + + + +
    +

    Sample address form for North America

    +

    * = required field

    + + + + +
    + + +
    + + + + + +
    + + + diff --git a/dist/samples/places-autocomplete-addressform/app/index.ts b/dist/samples/places-autocomplete-addressform/app/index.ts new file mode 100644 index 00000000..e67ed53b --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/index.ts @@ -0,0 +1,116 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// [START maps_places_autocomplete_addressform] +// 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.'); + }); +} + +// [START maps_places_autocomplete_addressform_fillform] +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(); +} +// [END maps_places_autocomplete_addressform_fillform] + +initAutocomplete(); +// [END maps_places_autocomplete_addressform] diff --git a/dist/samples/places-autocomplete-addressform/app/package.json b/dist/samples/places-autocomplete-addressform/app/package.json new file mode 100644 index 00000000..4bffcba6 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/package.json @@ -0,0 +1,14 @@ +{ + "name": "@js-api-samples/places-autocomplete-addressform", + "version": "1.0.0", + "scripts": { + "build": "tsc && bash ../jsfiddle.sh places-autocomplete-addressform && bash ../app.sh places-autocomplete-addressform && bash ../docs.sh places-autocomplete-addressform && npm run build:vite --workspace=. && bash ../dist.sh places-autocomplete-addressform", + "test": "tsc && npm run build:vite --workspace=.", + "start": "tsc && vite build --base './' && vite", + "build:vite": "vite build --base './'", + "preview": "vite preview" + }, + "dependencies": { + + } +} diff --git a/dist/samples/places-autocomplete-addressform/app/style.css b/dist/samples/places-autocomplete-addressform/app/style.css new file mode 100644 index 00000000..b3a1a67b --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/style.css @@ -0,0 +1,104 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +/* [START maps_places_autocomplete_addressform] */ +/* + * 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; +} +/* [END maps_places_autocomplete_addressform] */ diff --git a/dist/samples/places-autocomplete-addressform/app/tsconfig.json b/dist/samples/places-autocomplete-addressform/app/tsconfig.json new file mode 100644 index 00000000..366aabb0 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/app/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "esnext", + "target": "esnext", + "strict": true, + "noImplicitAny": false, + "lib": [ + "es2015", + "esnext", + "es6", + "dom", + "dom.iterable" + ], + "moduleResolution": "Node", + "jsx": "preserve" + } +} diff --git a/dist/samples/places-autocomplete-addressform/dist/assets/index-D7PTA2jX.js b/dist/samples/places-autocomplete-addressform/dist/assets/index-D7PTA2jX.js new file mode 100644 index 00000000..51a95520 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/dist/assets/index-D7PTA2jX.js @@ -0,0 +1,5 @@ +(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const t of document.querySelectorAll('link[rel="modulepreload"]'))o(t);new MutationObserver(t=>{for(const e of t)if(e.type==="childList")for(const c of e.addedNodes)c.tagName==="LINK"&&c.rel==="modulepreload"&&o(c)}).observe(document,{childList:!0,subtree:!0});function s(t){const e={};return t.integrity&&(e.integrity=t.integrity),t.referrerPolicy&&(e.referrerPolicy=t.referrerPolicy),t.crossOrigin==="use-credentials"?e.credentials="include":t.crossOrigin==="anonymous"?e.credentials="omit":e.credentials="same-origin",e}function o(t){if(t.ep)return;t.ep=!0;const e=s(t);fetch(t.href,e)}})();/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */let n,i,d,a;async function u(){const{Place:l,Autocomplete:r}=await google.maps.importLibrary("places");n=document.querySelector("gmp-place-autocomplete"),i=document.querySelector("#address1"),d=document.querySelector("#address2"),a=document.querySelector("#postcode");const s=document.querySelector(".my-button");n.focus(),n.addEventListener("gmp-select",async({placePrediction:o})=>{p(o)}),s.addEventListener("click",()=>{alert("In a real application, this would save the address details.")})}async function p(l){const{Place:r}=await google.maps.importLibrary("places"),s=l.toPlace();await s.fetchFields({fields:["addressComponents"]});let o="",t="";if(s.addressComponents){for(const e of s.addressComponents)e.types.includes("street_address")&&(o=`${e.longText} ${o}`),e.types.includes("street_number")&&(o=`${e.longText} ${o}`),e.types.includes("route")&&(o+=e.shortText),e.types.includes("postal_code")&&(t=`${e.longText}${t}`),e.types.includes("postal_code_suffix")&&(t=`${t}-${e.longText}`),e.types.includes("locality")&&(document.querySelector("#locality").value=e.longText),e.types.includes("administrative_area_level_1")&&(document.querySelector("#state").value=e.shortText),e.types.includes("country")&&(document.querySelector("#country").value=e.longText);i.value=o,a.value=t,d.focus()}}u(); diff --git a/dist/samples/places-autocomplete-addressform/dist/assets/index-Do5Iz5mf.css b/dist/samples/places-autocomplete-addressform/dist/assets/index-Do5Iz5mf.css new file mode 100644 index 00000000..cb335631 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/dist/assets/index-Do5Iz5mf.css @@ -0,0 +1,5 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */html,body{height:100%;margin:0;padding:0}body{font-family:Roboto,sans-serif;font-size:18px;color:#686868}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:.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:#686868;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:.5em}.full-field{flex:400px;margin:15px 15px 0 0}.address-row{display:flex;width:95%;gap:1.5em;padding-bottom:0}.slim-field-left,.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} diff --git a/dist/samples/places-autocomplete-addressform/dist/index.html b/dist/samples/places-autocomplete-addressform/dist/index.html new file mode 100644 index 00000000..cab23050 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/dist/index.html @@ -0,0 +1,71 @@ + + + + + + Place Autocomplete Address Form + + + + + + + + + + + +
    +

    Sample address form for North America

    +

    * = required field

    + + + + +
    + + +
    + + + + + +
    + + + diff --git a/dist/samples/places-autocomplete-addressform/docs/index.html b/dist/samples/places-autocomplete-addressform/docs/index.html new file mode 100644 index 00000000..e0c88b97 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/docs/index.html @@ -0,0 +1,71 @@ + + + + + + Place Autocomplete Address Form + + + + + + + + + + + +
    +

    Sample address form for North America

    +

    * = required field

    + + + + +
    + + +
    + + + + + +
    + + + diff --git a/dist/samples/places-autocomplete-addressform/docs/index.js b/dist/samples/places-autocomplete-addressform/docs/index.js new file mode 100644 index 00000000..873c7d3e --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/docs/index.js @@ -0,0 +1,87 @@ +"use strict"; +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +// [START maps_places_autocomplete_addressform] +// 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.'); + }); +} +// [START maps_places_autocomplete_addressform_fillform] +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(); +} +// [END maps_places_autocomplete_addressform_fillform] +initAutocomplete(); +// [END maps_places_autocomplete_addressform] diff --git a/dist/samples/places-autocomplete-addressform/docs/index.ts b/dist/samples/places-autocomplete-addressform/docs/index.ts new file mode 100644 index 00000000..e67ed53b --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/docs/index.ts @@ -0,0 +1,116 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// [START maps_places_autocomplete_addressform] +// 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.'); + }); +} + +// [START maps_places_autocomplete_addressform_fillform] +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(); +} +// [END maps_places_autocomplete_addressform_fillform] + +initAutocomplete(); +// [END maps_places_autocomplete_addressform] diff --git a/dist/samples/places-autocomplete-addressform/docs/style.css b/dist/samples/places-autocomplete-addressform/docs/style.css new file mode 100644 index 00000000..b3a1a67b --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/docs/style.css @@ -0,0 +1,104 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +/* [START maps_places_autocomplete_addressform] */ +/* + * 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; +} +/* [END maps_places_autocomplete_addressform] */ diff --git a/dist/samples/places-autocomplete-addressform/jsfiddle/demo.css b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.css new file mode 100644 index 00000000..ed134c88 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.css @@ -0,0 +1,104 @@ +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * 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; +} + diff --git a/dist/samples/places-autocomplete-addressform/jsfiddle/demo.details b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.details new file mode 100644 index 00000000..e153d6c2 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.details @@ -0,0 +1,7 @@ +name: places-autocomplete-addressform +authors: + - Geo Developer IX Documentation Team +tags: + - google maps +load_type: h +description: Sample code supporting Google Maps Platform JavaScript API documentation. diff --git a/dist/samples/places-autocomplete-addressform/jsfiddle/demo.html b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.html new file mode 100644 index 00000000..59360b93 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.html @@ -0,0 +1,71 @@ + + + + + + Place Autocomplete Address Form + + + + + + + + + + + +
    +

    Sample address form for North America

    +

    * = required field

    + + + + +
    + + +
    + + + + + +
    + + + diff --git a/dist/samples/places-autocomplete-addressform/jsfiddle/demo.js b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.js new file mode 100644 index 00000000..edacff21 --- /dev/null +++ b/dist/samples/places-autocomplete-addressform/jsfiddle/demo.js @@ -0,0 +1,87 @@ +"use strict"; +/** + * @license + * Copyright 2025 Google LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// 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(); + diff --git a/index.html b/index.html index f3a51451..c4620390 100644 --- a/index.html +++ b/index.html @@ -69,6 +69,7 @@

    Maps JSAPI Samples

  • place-class
  • place-nearby-search
  • place-text-search
  • +
  • places-autocomplete-addressform
  • react-ui-kit-place-details
  • react-ui-kit-place-details-compact
  • react-ui-kit-place-details-latlng
  • diff --git a/package-lock.json b/package-lock.json index 6d41fe14..7d1f4b74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1527,6 +1527,10 @@ "resolved": "samples/place-text-search", "link": true }, + "node_modules/@js-api-samples/places-autocomplete-addressform": { + "resolved": "samples/places-autocomplete-addressform", + "link": true + }, "node_modules/@js-api-samples/react-places-ui-kit-search-nearby": { "resolved": "samples/react-ui-kit-search-nearby", "link": true @@ -8944,6 +8948,10 @@ "name": "@js-api-samples/place-text-search", "version": "1.0.0" }, + "samples/places-autocomplete-addressform": { + "name": "@js-api-samples/places-autocomplete-addressform", + "version": "1.0.0" + }, "samples/react-places-ui-kit-search-nearby": { "version": "1.0.0", "extraneous": true,