Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ <h1>Maps JSAPI Samples</h1>
<li><a href='/samples/deckgl-kml/dist'>deckgl-kml</a></li>
<li><a href='/samples/deckgl-kml-updated/dist'>deckgl-kml-updated</a></li>
<li><a href='/samples/deckgl-polygon/dist'>deckgl-polygon</a></li>
<li><a href='/samples/js-api-loader-map/dist'>js-api-loader-map</a></li>
<li><a href='/samples/layer-data-quakes-red/dist'>layer-data-quakes-red</a></li>
<li><a href='/samples/layer-data-quakes-simple/dist'>layer-data-quakes-simple</a></li>
<li><a href='/samples/layer-data-simple/dist'>layer-data-simple</a></li>
Expand Down
57 changes: 28 additions & 29 deletions dist/samples/place-autocomplete-data-session/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,34 @@
-->
<!-- [START maps_place_autocomplete_data_session] -->
<html>
<head>
<title>Place Autocomplete Data API Session</title>
<head>
<title>Place Autocomplete Data API Session</title>

<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<!-- // [START maps_place_autocomplete_data_session_html] -->
<input id="input" type="text" placeholder="Search for a place..." />
<div id="title"></div>
<ul id="results"></ul>
<img
class="powered-by-google"
src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
alt="Powered by Google"
/>
<!-- // [END maps_place_autocomplete_data_session_html] -->

<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8&callback=init&libraries=places&v=weekly"
defer
></script>
</body>
<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>
<!-- // [START maps_place_autocomplete_data_session_html] -->
<gmp-map center="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID">
<div
class="controls"
slot="control-inline-start-block-start"
>
<input
type="text"
class="input"
placeholder="Search for a place..."
autocomplete="off"
/><!-- Turn off the input's own autocomplete (not supported by all browsers).-->
<div class="token-status"></div>
<div class="title"></div>
<ol class="results"></ol>
</div>
</gmp-map>
<!-- // [END maps_place_autocomplete_data_session_html] -->
</body>
</html>
<!-- [END maps_place_autocomplete_data_session] -->
145 changes: 96 additions & 49 deletions dist/samples/place-autocomplete-data-session/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,97 +5,144 @@
*/

// [START maps_place_autocomplete_data_session]
let titleElement;
let resultsContainerElement;
let inputElement;

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let titleElement = document.querySelector('.title') as HTMLElement;
let resultsContainerElement = document.querySelector('.results') as HTMLElement;
let inputElement = document.querySelector('input') as HTMLInputElement;
let tokenStatusElement = document.querySelector('.token-status') as HTMLElement;
let newestRequestId = 0;
let tokenCount = 0;

// Add an initial request body.
const request = {
// Create an initial request body.
const request: google.maps.places.AutocompleteRequest = {
input: '',
locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
origin: { lat: 37.7893, lng: -122.4039 },
includedPrimaryTypes: ['restaurant'],
language: 'en-US',
region: 'us',
};

function init() {
titleElement = document.getElementById('title');
resultsContainerElement = document.getElementById('results');
inputElement = document.querySelector('input');
includedPrimaryTypes: [
'restaurant',
'cafe',
'museum',
'park',
'botanical_garden',
],
}

async function init() {
await google.maps.importLibrary('maps');
innerMap = mapElement.innerMap;
innerMap.setOptions({
mapTypeControl: false,
});

// Update request center and bounds when the map bounds change.
google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
request.locationRestriction = innerMap.getBounds();
request.origin = innerMap.getCenter();
});

inputElement.addEventListener('input', makeAutocompleteRequest);
refreshToken(request);
}

async function makeAutocompleteRequest(inputEvent) {
// Reset elements and exit if an empty string is received.
if (inputEvent.target.value == '') {
titleElement.innerText = '';
// To avoid race conditions, store the request ID and compare after the request.
const requestId = ++newestRequestId;

const { AutocompleteSuggestion } = (await google.maps.importLibrary(
'places'
)) as google.maps.PlacesLibrary;

if (!inputEvent.target?.value) {
titleElement.textContent = '';
resultsContainerElement.replaceChildren();
return;
}

// Add the latest char sequence to the request.
request.input = inputEvent.target.value;

// To avoid race conditions, store the request ID and compare after the request.
const requestId = ++newestRequestId;
request.input = (inputEvent.target as HTMLInputElement).value;

// Fetch autocomplete suggestions and show them in a list.
// @ts-ignore
const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
const { suggestions } =
await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

// If the request has been superseded by a newer request, do not render the output.
if (requestId !== newestRequestId) return;

titleElement.innerText = `Query predictions for "${request.input}"`;
titleElement.innerText = `Place predictions for "${request.input}"`;

// Clear the list first.
resultsContainerElement.replaceChildren();

for (const suggestion of suggestions) {
const placePrediction = suggestion.placePrediction;

if (!placePrediction) {
continue;
}

// Create a link for the place, add an event handler to fetch the place.
const a = document.createElement('a');
a.addEventListener('click', () => {
onPlaceSelected(placePrediction!.toPlace());
// We are using a button element to take advantage of its a11y capabilities.
const placeButton = document.createElement('button');
placeButton.addEventListener('click', () => {
onPlaceSelected(placePrediction.toPlace());
});
a.innerText = placePrediction!.text.toString();
placeButton.textContent = placePrediction.text.toString();
placeButton.classList.add('place-button');

// Create a new list item element.
const li = document.createElement('li');
li.appendChild(a);
li.appendChild(placeButton);
resultsContainerElement.appendChild(li);
}
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
async function onPlaceSelected(place: google.maps.places.Place) {
const { AdvancedMarkerElement } = (await google.maps.importLibrary(
'marker'
)) as google.maps.MarkerLibrary;

await place.fetchFields({
fields: ['displayName', 'formattedAddress'],
fields: ['displayName', 'formattedAddress', 'location'],
});
const placeText = document.createTextNode(`${place.displayName}: ${place.formattedAddress}`);
resultsContainerElement.replaceChildren(placeText);
titleElement.innerText = 'Selected Place:';

resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`;
titleElement.textContent = 'Selected Place:';
inputElement.value = '';
refreshToken(request);

await refreshToken();

// Remove the previous marker, if it exists.
if (marker) {
marker.remove();
}

// Create a new marker.
marker = new AdvancedMarkerElement({
map: innerMap,
position: place.location,
title: place.displayName,
})

// Center the map on the selected place.
if (place.location) {
innerMap.setCenter(place.location);
innerMap.setZoom(15);
}
}

// Helper function to refresh the session token.
function refreshToken(request) {
async function refreshToken() {
const { AutocompleteSessionToken } = (await google.maps.importLibrary(
'places'
)) as google.maps.PlacesLibrary;

// Increment the token counter.
tokenCount++;

// Create a new session token and add it to the request.
request.sessionToken = new google.maps.places.AutocompleteSessionToken();
request.sessionToken = new AutocompleteSessionToken();
tokenStatusElement.textContent = `Session token count: ${tokenCount}`;
}

declare global {
interface Window {
init: () => void;
}
}
window.init = init;
init();
// [END maps_place_autocomplete_data_session]
void 0; // No-op to preserve the last region tag comment.
export { };
51 changes: 46 additions & 5 deletions dist/samples/place-autocomplete-data-session/app/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,55 @@ body {
padding: 0;
}

a {
.place-button {
height: 3rem;
width: 100%;
background-color: transparent;
text-align: left;
border: none;
cursor: pointer;
text-decoration: underline;
color: blue;
}

input {
.place-button:focus-visible {
outline: 2px solid #0056b3;
border-radius: 2px;
}

.input {
width: 300px;
font-size: small;
margin-bottom: 1rem;
}

/* Styles for the floating panel */
.controls {
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
font-family: sans-serif;
font-size: small;
margin: 12px;
padding: 1rem;
}

.title {
font-weight: bold;
margin-top: 1rem;
margin-bottom: 0.5rem;
}

.results {
list-style-type: none;
margin: 0;
padding: 0;
}

.results li:not(:last-child) {
border-bottom: 1px solid #ddd;
}

.results li:hover {
background-color: #eee;
}

/* [END maps_place_autocomplete_data_session] */
/* [END maps_place_autocomplete_data_session] */

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

Loading