google maps
by bgoonz
HTML
<!DOCTYPE html>
<html>
<head>
<title>Locator</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://www.gstatic.com/external_hosted/handlebars/v4.7.6/handlebars.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<script>
const CONFIGURATION = {"capabilities":{"input":true,"autocomplete":true,"directions":true,"distanceMatrix":true,"details":true},"locations":[{"title":"150 Henley Pl","address1":"150 Henley Pl","address2":"Weehawken, NJ 07086, USA","coords":{"lat":40.76723632567452,"lng":-74.01773125787058},"placeId":"ChIJ05SPRTBYwokRTrbKgS5R3Yk"}],"mapOptions":{},"mapsApiKey":"AIzaSyBVYIr57O3fkBCZRco4n-Zhtp3eR9sQovk"};
function initMap() {
new LocatorPlus(CONFIGURATION);
}
</script>
<script id="locator-result-items-tmpl" type="text/x-handlebars-template">
{{#each locations}}
<li class="location-result" data-location-index="{{index}}">
<button class="select-location">
<h2 class="name">{{title}}</h2>
</button>
<div class="address">{{address1}}<br>{{address2}}</div>
<button class="details-button">
View details
</button>
{{#if travelDistanceText}}
<div class="distance">{{travelDistanceText}}</div>
{{/if}}
{{#if ../showDirectionsButton}}
<button class="show-directions" title="Show directions to this location">
<svg width="34" height="34" viewBox="0 0 34 34"
fill="none" xmlns="http://www.w3.org/2000/svg" alt="Show directions">
<path d="M17.5867 9.24375L17.9403 8.8902V8.8902L17.5867 9.24375ZM16.4117 9.24375L16.7653 9.59731L16.7675 9.59502L16.4117 9.24375ZM8.91172 16.7437L8.55817 16.3902L8.91172 16.7437ZM8.91172 17.9229L8.55817 18.2765L8.55826 18.2766L8.91172...
CSS
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map-container {
width: 100%;
height: 100%;
position: relative;
font-family: "Roboto", sans-serif;
box-sizing: border-box;
}
#map-container button {
background: none;
color: inherit;
border: none;
padding: 0;
font: inherit;
font-size: inherit;
cursor: pointer;
}
#map {
position: absolute;
left: 22em;
top: 0;
right: 0;
bottom: 0;
}
#locations-panel {
position: absolute;
left: 0;
width: 22em;
top: 0;
bottom: 0;
overflow-y: auto;
background: white;
padding: 0.5em;
box-sizing: border-box;
}
@media only screen and (max-width: 876px) {
#map {
left: 0;
bottom: 50%;
}
#locations-panel {
top: 50%;
right: 0;
width: unset;
}
}
#locations-panel-list > header {
padding: 1.4em 1.4em 0 1.4em;
}
#locations-panel-list h1.search-title {
font-size: 1em;
font-weight: 500;
margin: 0;
}
#locations-panel-list h1.search-title > img {
vertical-align: bottom;
margin-top: -1em;
}
#locations-panel-list .search-input {
width: 100%;
margin-top: 0.8em;
position: relative;
}
#locations-panel-list .search-input input {
width: 100%;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 0.3em;
height: 2.2em;
box-sizing: border-box;
padding: 0 2.5em 0 1em;
font-size: 1em;
}
#locations-panel-list .search-input-overlay {
position: absolute;
}
#locations-panel-list .search-input-overlay.search {
right: 2px;
top: 2px;
bottom: 2px;
width: 2.4em;
}
#locations-panel-list .search-input-overlay.search button {
width: 100%;
height: 100%;
border-radius: 0.2em;
color: black;
background: transparent;
}
#locations-panel-list .search-input-overlay.search .icon {
margin-top: 0.05em;
vertical-align: top;
}
#locations-panel-list .section-name {
font-weight: 500;
font-size: 0.9em;
margin: 1.8em 0 1em 1.5em;
}
#locations-panel-list .location-result {
position: relative;
padding: 0.8em 3.5em 0.8em...
JavaScript
'use strict';
/** Hide a DOM element. */
function hideElement(el) {
el.style.display = 'none';
}
/** Show a DOM element that has been hidden. */
function showElement(el) {
el.style.display = 'block';
}
/**
* Defines an instance of the Locator+ solution, to be instantiated
* when the Maps library is loaded.
*/
function LocatorPlus(configuration) {
const locator = this;
locator.locations = configuration.locations || [];
locator.capabilities = configuration.capabilities || {};
const mapEl = document.getElementById('map');
locator.panelListEl = document.getElementById('locations-panel-list');
const sectionNameEl =
document.getElementById('location-results-section-name');
const resultsContainerEl = document.getElementById('location-results-list');
const itemsTemplate = Handlebars.compile(
document.getElementById('locator-result-items-tmpl').innerHTML);
locator.searchLocation = null;
locator.searchLocationMarker = null;
locator.selectedLocationIdx = null;
locator.userCountry = null;
// Initialize the map -------------------------------------------------------
const mapOptions = configuration.mapOptions;
locator.map = new google.maps.Map(mapEl, {
fullscreenControl: mapOptions.fullscreenControl,
zoomControl: mapOptions.zoomControl,
streetViewControl: mapOptions.streetViewControl,
mapTypeControl: mapOptions.mapTypeControl,
mapTypeControlOptions: {
position: google.maps.ControlPosition.TOP_RIGHT,
},
});
// Store selection.
const selectResultItem = function(locationIdx, panToMarker) {
locator.selectedLocationIdx = locationIdx;
for (let locationElem of resultsContainerEl.children) {
locationElem.classList.remove('selected');
if (getResultIndex(locationElem) === locator.selectedLocationIdx) {
locationElem.classList.add('selected');
}
}
if (panToMarker && (locationIdx != null)) {
locator.map.panTo(locator.locations[locationIdx].coords);
...