У вас есть все данные, необходимые для открытия информационного окна при щелчке боковой панели.
Сделайте то же самое, что и при нажатии на маркер:
function openInfoWindowOnMarker(feature) {
console.log(feature);
const name = feature.getProperty('name');
const address = feature.getProperty('address');
const phone = feature.getProperty('phone');
const position = feature.getGeometry().get();
const content = `<h5>${name}</h5><p>${address}</p><p>${phone}</p>`;
infoWindow.setContent(content);
infoWindow.setPosition(position);
infoWindow.setOptions({
pixelOffset: new google.maps.Size(0, -30)
});
infoWindow.open(map);
}
infoWindow = new google.maps.InfoWindow();
// Show the information for a store when its marker is clicked.
map.data.addListener('click', (event) => {
openInfoWindowOnMarker(event.feature)
});
Тогда где находится боковая панель Если вы нажмете на запись на боковой панели, вызовите ту же функцию.
stores.forEach((store) => {
console.log(store);
// Add store details with text formatting
const name = document.createElement('p');
name.setAttribute('id', 'locationName');
name.classList.add('place');
const currentStore = data.getFeatureById(store.storeid);
name.addEventListener('click', (function(currentStore) {
return function() {
openInfoWindowOnMarker(currentStore);
}})(currentStore));
name.textContent = currentStore.getProperty('name');
panel.appendChild(name);
const distanceText = document.createElement('p');
distanceText.classList.add('distanceText');
distanceText.textContent = store.distanceText;
panel.appendChild(distanceText);
});
Для того, чтобы сделать коды map
и infoWindow
доступными для кода, потребовалось внести несколько других изменений.
подтверждение концепции скрипта
фрагмент кода:
var infoWindow;
var map;
function initMap() {
// Create the map.
map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: {
lat: 32.434521,
lng: -86.333977
},
// styles: mapStyle,
});
// Load the stores GeoJSON onto the map.
map.data.addGeoJson(geoJsonData, {
idPropertyName: 'storeid'
});
// Define the custom marker icons, using the store's "category".
map.data.setStyle((feature) => {
return {
icon: {
url: 'https://staging.ymcamontgomery.org/wp-content/uploads/2020/02/map-marker-1.svg',
scaledSize: new google.maps.Size(64, 64),
},
};
});
const apiKey = 'AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk';
infoWindow = new google.maps.InfoWindow();
// Show the information for a store when its marker is clicked.
map.data.addListener('click', (event) => {
openInfoWindowOnMarker(event.feature)
});
// SEARCH BAR
// Build and add the search bar
const card = document.createElement('div');
const titleBar = document.createElement('div');
const title = document.createElement('div');
const container = document.createElement('div');
const magnify = document.createElement('div');
const input = document.createElement('input');
const options = {
types: ['(regions)'],
componentRestrictions: {
country: 'us'
},
};
card.setAttribute('id', 'pac-card');
title.setAttribute('id', 'title');
title.textContent = 'Find the nearest location';
titleBar.appendChild(title);
container.setAttribute('id', 'pac-container');
magnify.setAttribute('id', 'magnify');
input.setAttribute('id', 'pac-input');
input.setAttribute('type', 'text');
input.setAttribute('placeholder', 'ZIP CODE');
input.setAttribute('value', 'Montgomery');
container.appendChild(input);
let parent = document.getElementById('map-hero');
parent.appendChild(card);
card.appendChild(titleBar);
card.appendChild(container);
let magnifyParent = document.getElementById('pac-container');
magnifyParent.appendChild(magnify);
// map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
// Make the search bar into a Places Autocomplete search bar and select
// which detail fields should be returned about the place that
// the user selects from the suggestions.
const autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.setFields(
['address_components', 'geometry', 'name']);
// END SEARCH BAR
// Press Enter to Search Zip Code
var pac_input = document.getElementById('pac-input');
(function pacSelectFirst(input) {
// store the original event binding function
var _addEventListener = (input.addEventListener) ? input.addEventListener : input.attachEvent;
function addEventListenerWrapper(type, listener) {
// Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected,
// and then trigger the original listener.
if (type == "keydown") {
var orig_listener = listener;
listener = function(event) {
var suggestion_selected = $(".pac-item-selected").length > 0;
if (event.which == 13 && !suggestion_selected) {
var simulated_downarrow = $.Event("keydown", {
keyCode: 40,
which: 40
});
orig_listener.apply(input, [simulated_downarrow]);
}
orig_listener.apply(input, [event]);
};
}
_addEventListener.apply(input, [type, listener]);
}
input.addEventListener = addEventListenerWrapper;
input.attachEvent = addEventListenerWrapper;
var autoComplete = new google.maps.places.Autocomplete(input);
autoComplete.setTypes(['regions'])
// autoComplete.unbindAll();
})(pac_input);
//End Press Enter to Search Zip Code
//Click magnifying glass to search
document.getElementById('magnify').onclick = function() {
var input = document.getElementById('pac-input');
function no_op() {}
google.maps.event.trigger(input, 'focus', {});
google.maps.event.trigger(input, 'keydown', {
keyCode: 40, // arrow down
stopPropagation: no_op, // No-op function in order to prevent error
preventDefault: no_op,
});
google.maps.event.trigger(input, 'keydown', {
keyCode: 13
}); // enter
google.maps.event.trigger(this, 'focus', {});
};
//End Click magnifying glass to search
// Set the origin point when the user selects an address
const originMarker = new google.maps.Marker({
map: map
});
originMarker.setVisible(false);
let originLocation = map.getCenter();
autocomplete.addListener('place_changed', async () => {
originMarker.setVisible(false);
originLocation = map.getCenter();
const place = autocomplete.getPlace();
if (!place.geometry) {
// User entered the name of a Place that was not suggested and
// pressed the Enter key, or the Place Details request failed.
window.alert('No address available for input: \'' + place.name + '\'');
return;
}
// Recenter the map to the selected address
originLocation = place.geometry.location;
map.setCenter(originLocation);
map.setZoom(9);
console.log(place);
originMarker.setPosition(originLocation);
originMarker.setVisible(true);
// Use the selected address as the origin to calculate distances
// to each of the store locations
const rankedStores = await calculateDistances(map.data, originLocation);
showStoresList(map.data, rankedStores);
return;
});
}
function openInfoWindowOnMarker(feature) {
console.log(feature);
const name = feature.getProperty('name');
const address = feature.getProperty('address');
const phone = feature.getProperty('phone');
const position = feature.getGeometry().get();
const content = `<h5>${name}</h5><p>${address}</p><p>${phone}</p>`;
infoWindow.setContent(content);
infoWindow.setPosition(position);
infoWindow.setOptions({
pixelOffset: new google.maps.Size(0, -30)
});
infoWindow.open(map);
}
// Calculate Distance
async function calculateDistances(data, origin) {
const stores = [];
const destinations = [];
// Build parallel arrays for the store IDs and destinations
data.forEach((store) => {
const storeNum = store.getProperty('storeid');
const storeLoc = store.getGeometry().get();
stores.push(storeNum);
destinations.push(storeLoc);
});
// Retrieve the distances of each store from the origin
// The returned list will be in the same order as the destinations list
const service = new google.maps.DistanceMatrixService();
const getDistanceMatrix =
(service, parameters) => new Promise((resolve, reject) => {
service.getDistanceMatrix(parameters, (response, status) => {
if (status != google.maps.DistanceMatrixStatus.OK) {
reject(response);
} else {
const distances = [];
const results = response.rows[0].elements;
for (let j = 0; j < results.length; j++) {
const element = results[j];
if (element.status == "OK") {
const distanceText = element.distance.text;
const distanceVal = element.distance.value;
const distanceObject = {
storeid: stores[j],
storeLoc: destinations[j],
distanceText: distanceText,
distanceVal: distanceVal,
};
distances.push(distanceObject);
}
}
resolve(distances);
}
});
});
const distancesList = await getDistanceMatrix(service, {
origins: [origin],
destinations: destinations,
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
});
distancesList.sort((first, second) => {
return first.distanceVal - second.distanceVal;
});
return distancesList;
}
// End Calculate Distance
//Show Closest Location List
function showStoresList(data, stores) {
if (stores.length == 0) {
console.log('empty stores');
return;
}
let panel = document.createElement('div');
// If the panel already exists, use it. Else, create it and add to the page.
if (document.getElementById('panel')) {
panel = document.getElementById('panel');
// If panel is already open, close it
if (panel.classList.contains('open')) {
panel.classList.remove('open');
}
} else {
panel.setAttribute('id', 'panel');
let parent = document.getElementById('map');
parent.appendChild(panel);
// const body = document.body;
// body.insertBefore(panel, body.childNodes[0]);
}
// Clear the previous details
while (panel.lastChild) {
panel.removeChild(panel.lastChild);
}
stores.forEach((store) => {
console.log(store);
// Add store details with text formatting
const name = document.createElement('p');
name.setAttribute('id', 'locationName');
name.classList.add('place');
const currentStore = data.getFeatureById(store.storeid);
name.addEventListener('click', (function(currentStore) {
return function() {
openInfoWindowOnMarker(currentStore);
}})(currentStore));
name.textContent = currentStore.getProperty('name');
panel.appendChild(name);
const distanceText = document.createElement('p');
distanceText.classList.add('distanceText');
distanceText.textContent = store.distanceText;
panel.appendChild(distanceText);
});
// Open the panel
panel.classList.add('open');
return;
}
//End Show Closest Location List
var geoJsonData = {
"type": "FeatureCollection",
"features": [{
"geometry": {
"type": "Point",
"coordinates": [-86.192867,
32.346155
]
},
"type": "Feature",
"properties": {
"name": "Place 1",
"address": "The Address",
"phone": "The Number",
"storeid": "01"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [-86.305915,
32.366245
]
},
"type": "Feature",
"properties": {
"name": "Place 2",
"address": "The Address",
"phone": "The Number",
"storeid": "02"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [-85.7077266,
32.430237
]
},
"type": "Feature",
"properties": {
"name": "Tuskegee",
"address": "Tuskegee",
"phone": "The Number",
"storeid": "03"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [151.2092955,
-33.8688197
]
},
"type": "Feature",
"properties": {
"name": "Sydney",
"address": "Sydney NSW",
"phone": "The Number",
"storeid": "04"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [-74.0059728 ,
40.7127753
]
},
"type": "Feature",
"properties": {
"name": "New York",
"address": "New York, NY",
"phone": "The Number",
"storeid": "05"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [-71.05888 ,
42.3600825
]
},
"type": "Feature",
"properties": {
"name": "Boston",
"address": "Boston, MA",
"phone": "The Number",
"storeid": "06"
}
},
{
"geometry": {
"type": "Point",
"coordinates": [-80.1917902,
25.7616798
]
},
"type": "Feature",
"properties": {
"name": "Miami",
"address": "Miami, FL",
"phone": "The Number",
"storeid": "07"
}
},
]
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
/* #map {
height: 100%;
} */
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 400px;
width: 100%;
}
.map-hero {
/* background-image: url('my url'); */
background-size: cover;
background-position: center;
min-height: 355px;
display: flex;
flex-direction: column;
justify-content: center;
}
.center-info-bar {
margin-bottom: 0;
}
.sidebar {
display: none;
}
.content {
width: 100%;
}
.gm-style-iw-c {
padding: 25px;
width: 300px;
}
.gm-style-iw-d {
height: auto;
}
.map-loc-name {
font-size: 15px;
font-weight: bold;
width: 100%;
margin-bottom: 15px;
}
#pac-card {
background-color: #fff;
border-radius: 2px 0 0 2px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
font-family: Roboto;
margin: 10px 10px 0 0;
-moz-box-sizing: border-box;
outline: none;
// custom
max-width: 300px;
background: transparent;
box-shadow: none;
margin: 0 auto;
}
#pac-container {
padding-top: 12px;
padding-bottom: 12px;
margin-right: 12px;
display: flex;
align-items: center;
}
#pac-input {
text-overflow: ellipsis;
// custom
width: 100%;
padding: 15px;
border: 3px solid #C11589;
border-radius: 10px 0 0 10px;
background: transparent;
color: #000;
font-size: 18px;
font-weight: bold;
font-family: 'Cachet-Bold', Verdana, sans-serif;
}
#pac-input::placeholder {
color: #fff;
font-family: 'Cachet-Bold', Verdana, sans-serif;
font-weight: bold;
font-size: 18px;
}
input:focus {
box-shadow: none;
}
#magnify {
width: 50px;
height: 58px;
border-radius: 0 10px 10px 0;
background-color: #C11589;
/* background-image: url('my url'); */
background-size: 80%;
background-position: center;
background-repeat: no-repeat;
}
#magnify:hover {
cursor: pointer;
}
#title {
color: #fff;
background-color: #acbcc9;
font-size: 18px;
font-weight: 400;
padding: 6px 12px;
// custom
display: none;
}
.hidden {
display: none;
}
/* Styling for an info pane that slides out from the left.
* Hidden by default. */
#panel {
height: 100%;
width: null;
background-color: white;
position: absolute;
z-index: 1;
overflow-x: hidden;
transition: all .2s ease-out;
}
.open {
width: 250px;
}
.place {
font-family: 'open sans', arial, sans-serif;
font-size: 1.2em;
font-weight: 500;
margin-block-end: 0px;
padding-left: 18px;
padding-right: 18px;
}
.distanceText {
color: silver;
font-family: 'open sans', arial, sans-serif;
font-size: 1em;
font-weight: 400;
margin-block-start: 0.25em;
padding-left: 18px;
padding-right: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map-hero" class="map-hero">
<h1 class="white center">GET STARTED BY ENTERING YOUR ZIP CODE</h1>
<h4 class="white center">You can also zoom and drag to find a location nearest you</h4>
</div>
<div class="center-info-bar">
<div id="map"></div>
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=places" async defer></script>