I created a places search google map that likes to search for places like types of schools, I made a marker for both private and public, the search box works, but when I click enter, It does not show the public/private schools, Is this because of my code? on icon? or marker?
The only problem is when I click enter, It does not display its markers
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Places Search Box</title>
<style>
/* 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;
}
#description {
font-family: Roboto;
font-size: 15px;
font-weight: 300;
}
#infowindow-content .title {
font-weight: bold;
}
#infowindow-content {
display: none;
}
#map #infowindow-content {
display: inline;
}
.pac-card {
margin: 10px 10px 0 0;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
background-color: #fff;
font-family: Roboto;
}
#pac-container {
padding-bottom: 12px;
margin-right: 12px;
}
.pac-controls {
display: inline-block;
padding: 5px 11px;
}
.pac-controls label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 400px;
}
#pac-input:focus {
border-color: #4d90fe;
}
#title {
color: #fff;
background-color: #4d90fe;
font-size: 25px;
font-weight: 500;
padding: 6px 12px;
}
#target {
width: 345px;
}
</style>
</head>
<body>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map"></div>
<script>
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -33.8688,
lng: 151.2195
},
zoom: 13,
mapTypeId: 'roadmap'
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icons = {
'Public school': {
icon: 'http://i68.tinypic.com/xcnnz4.png'
},
'Private school': {
icon: 'http://i67.tinypic.com/2utkz8k.png'
}
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
initAutocomplete();
</script>
</body>
</html>
Icon is not declared. You need to check the input to see if Private or Public school was entered and then set the icon accordingly.
// Create a marker for each place.
var marker = new google.maps.Marker({
map: map,
title: place.name,
position: place.geometry.location
});
if(place.name.toLowerCase() === 'private school') {
marker.setIcon('http://i67.tinypic.com/2utkz8k.png');
}
else if(place.name.toLowerCase() === 'public school') {
marker.setIcon('http://i68.tinypic.com/xcnnz4.png');
}
markers.push(marker);
This question already has answers here:
Google Maps JS API v3 - Simple Multiple Marker Example
(15 answers)
Closed 6 years ago.
i've created a google maps, which retrieve data from a csv file. This seem to work fine, however when i loop through all the objects the infoWindow does not seem to work. i guess this is due to the fact that the marker variable is inside a for loop. i've tried to move the code to inside the loop, however this result in the infoWindow placed randomly on the map instead above the clicked marker. How can i achieve the infoWindow to work with multiple markers?
db.csv example
40.740;-74.18;test;haha;
40.740;-74.20;test;haha;
html & java
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="normalize.css">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<div id="mapContainer">
<div id="map"></div>
</div>
<div id="abc">
<div id="popupContact">
<section class="register">
<h1>CAMP INFORMATIONER:</h1>
<form method="post" action="index.html">
<div class="reg_section personal_info">
<input type="text" name="username" value="" placeholder="Campnavn">
<textarea name="textarea" id="description" placeholder="Beskrivelse"></textarea>
</div>
<div>
<span class="submit" style="text-align: left; padding: 0 10px;"><input TYPE="button"name="commit" value="Tilføj" onclick="placeMarker(currentMarker, document.getElementById('description'));"></span>
<span class="submit" style="text-align: right; padding: 0 10px;"><input TYPE="button" name="commit" value="Fortryd" onclick="div_hide();"></span>
</div>
</form>
</section>
</div>
</div>
</div>
<script>
var mapCanvas;
var currentMarker;
function initialize() {
var myOptions = {
center: {lat: 40.740, lng: -74.18},
zoom : 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapCanvas = new google.maps.Map(document.getElementById("mapContainer"), myOptions);
var returnValue = "";
var request = new XMLHttpRequest();
// Read the lat/long info for markers
request.open("GET", "db.csv", false);
request.send(null);
returnValue = request.responseText;
// Convert our data from the CVS file to a usable array
var data = CSVToArray(returnValue);
for (var i = 0; i < data.length; i++)
{
// Create a lat/long object readable by Google
var myLatlng = new google.maps.LatLng(parseFloat(data[i][0]), parseFloat(data[i][1]));
// Generate a marker from the lat/long object and add it to the map
var marker = new google.maps.Marker({
position: myLatlng,
map: mapCanvas,
title: data[i][2],
description: data[i][3]
});
}
var imageBounds = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
};
historicalOverlay = new google.maps.GroundOverlay(
'http://i.stack.imgur.com/0mgx2.jpg',
imageBounds);
historicalOverlay.setMap(mapCanvas);
// This event listener calls addMarker() when the map is clicked.
google.maps.event.addListener(historicalOverlay, 'click', function(e) {
console.log("clicked'");
currentMarker = e.latLng;
infowindow.close();
div_show();
});
//Changes zoom levels when the projection is available.
google.maps.event.addListenerOnce(mapCanvas, "projection_changed", function(){
mapCanvas.setMapTypeId(google.maps.MapTypeId.HYBRID); //Changes the MapTypeId in short time.
setZoomLimit(mapCanvas, google.maps.MapTypeId.ROADMAP);
setZoomLimit(mapCanvas, google.maps.MapTypeId.HYBRID);
setZoomLimit(mapCanvas, google.maps.MapTypeId.SATELLITE);
setZoomLimit(mapCanvas, google.maps.MapTypeId.TERRAIN);
mapCanvas.setMapTypeId(google.maps.MapTypeId.ROADMAP); //Sets the MapTypeId to original.
});
// InfoWindow content
var content = '<div id="iw-container">' +
'<div class="iw-title">title</div>' +
'<div class="iw-content">' +
'<p>Founded in 1824, the Porcelain Factory of Vista Alegre was the first industrial unit dedicated to porcelain production in Portugal. For the foundation and success of this risky industrial development was crucial the spirit of persistence of its founder, José Ferreira Pinto Basto. Leading figure in Portuguese society of the nineteenth century farm owner, daring dealer, wisely incorporated the liberal ideas of the century, having become "the first example of free enterprise" in Portugal.</p>' +
'</div>' +
'<div class="iw-bottom-gradient"></div>' +
'</div>';
// A new Info Window is created and set content
var infowindow = new google.maps.InfoWindow({
content: content,
// Assign a maximum value for the width of the infowindow allows
// greater control over the various content elements
maxWidth: 350
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(mapCanvas, marker);
//title
document.getElementById("iw-title").innerHTML = marker.title;
//description
document.getElementById("iw-content p").innerHTML = marker.description;
});
// Event that closes the Info Window with a click on the map
google.maps.event.addListener(mapCanvas, 'click', function() {
infowindow.close();
});
google.maps.event.addListener(infowindow, 'domready', function() {
// Reference to the DIV that wraps the bottom of infowindow
var iwOuter = $('.gm-style-iw');
/* Since this div is in a position prior to .gm-div style-iw.
* We use jQuery and create a iwBackground variable,
* and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
*/
var iwBackground = iwOuter.prev();
// Removes background shadow DIV
iwBackground.children(':nth-child(2)').css({'display' : 'none'});
// Removes white background DIV
iwBackground.children(':nth-child(4)').css({'display' : 'none'});
// Moves the infowindow 115px to the right.
iwOuter.parent().parent().css({left: '115px'});
// Moves the shadow of the arrow 76px to the left margin.
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Moves the arrow 76px to the left margin.
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});
// Changes the desired tail shadow color.
iwBackground.children(':nth-child(3)').find('div').children().css({'z-index' : '1'});
// Reference to the div that groups the close button elements.
var iwCloseBtn = iwOuter.next();
// Apply the desired effect to the close button
iwCloseBtn.css({opacity: '1', right: '38px', top: '3px', border: '7px solid #fff', 'border-radius': '13px', 'box-shadow': '0 0 5px #7D0F33'});
// If the content of infowindow not exceed the set maximum height, then the gradient is removed.
if($('.iw-content').height() < 140){
$('.iw-bottom-gradient').css({display: 'none'});
}
// The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
iwCloseBtn.mouseout(function(){
$(this).css({opacity: '1'});
});
});
}
function div_show() {
$('#abc').fadeIn(400);
}
//Function to Hide Popup
function div_hide(){
$('#abc').fadeOut(400);
}
function placeMarker(location, label) {
var marker = new google.maps.Marker({
position: location,
map: mapCanvas,
labelContent : label
});
div_hide();
}
function setZoomLimit(map, mapTypeId){
//Gets MapTypeRegistry
var mapTypeRegistry = map.mapTypes;
//Gets the specified MapType
var mapType = mapTypeRegistry.get(mapTypeId);
//Sets limits to MapType
mapType.maxZoom = 15; //It doesn't work with SATELLITE and HYBRID maptypes.
mapType.minZoom = 15;
}
function CSVToArray(strData, strDelimiter ){
// Check to see if the delimiter is defined. If not,
// then default to comma.
strDelimiter = (strDelimiter || ";");
// Create a regular expression to parse the CSV values.
var objPattern = new RegExp(
(
// Delimiters.
"(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
// Quoted fields.
"(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
// Standard fields.
"([^\"\\" + strDelimiter + "\\r\\n]*))"
), "gi");
// Create an array to hold our data. Give the array
// a default empty first row.
var arrData = [[]];
// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;
// Keep looping over the regular expression matches
// until we can no longer find a match.
while (arrMatches = objPattern.exec( strData ))
{
// Get the delimiter that was found.
var strMatchedDelimiter = arrMatches[ 1 ];
// Check to see if the given delimiter has a length
// (is not the start of string) and if it matches
// field delimiter. If id does not, then we know
// that this delimiter is a row delimiter.
if (strMatchedDelimiter.length && (strMatchedDelimiter != strDelimiter))
{
// Since we have reached a new row of data,
// add an empty row to our data array.
arrData.push( [] );
}
// Now that we have our delimiter out of the way,
// let's check to see which kind of value we
// captured (quoted or unquoted).
if (arrMatches[ 2 ]){
// We found a quoted value. When we capture
// this value, unescape any double quotes.
var strMatchedValue = arrMatches[ 2 ].replace(
new RegExp( "\"\"", "g" ),
"\""
);
} else
{
// We found a non-quoted value.
var strMatchedValue = arrMatches[ 3 ];
}
// Now that we have our value string, let's add
// it to the data array.
arrData[ arrData.length - 1 ].push( strMatchedValue );
}
// Return the parsed data.
return( arrData );
}
google.maps.event.addDomListener(window, "load", initialize);
</script>
<body>
CSS
/* Author : iMomen
Website: www.iMomen.com
E-mail : Coder#iMomen.com
*/
#mapContainer {
height: 100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
position: relative;
}
#map {
height: 100%;
}
.gm-style-mtc {
display: none;
}
.gmnoprint {
display: none;
}
#abc {
width:100%;
height:100%;
top:0;
left:0;
display:none;
position:fixed;
background-color: rgba(0,0,0, .5);
overflow:auto;
}
div#popupContact {
width: 350px; /*can be in percentage also.*/
margin: 0;
margin: 0;
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
}
div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
html, body {
height:100%;
width: 100%;
margin-left: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-top: 0px;
overflow:hidden;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a {
color:#FF3679;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.container {
width: 350px;
margin-left: auto;
margin-right: auto;
}
.reg_section {
padding:0;
margin: 10px 0;
border-bottom: 1px dotted #eee;
}
.reg_section h3 {
font-size: 13px;
margin: 5px 0;
color: #C4A2A2;
}
/* Form */
.register {
text-align: center;
position: relative;
padding: 20px 20px 20px 20px;
background: #fff;
border-radius: 3px;
}
.register:before {
content: '';
position: absolute;
top: -8px;
right: -8px;
bottom: -8px;
left: -8px;
z-index: -1;
background:rgba(255, 173, 200, 0.08);
border-radius:7px;
-webkit-border-radius: 7px;
}
.register h1 {
margin: -20px -20px 0;
line-height: 40px;
font-size: 15px;
font-weight: bold;
color:#694551;
text-align: center;
border-bottom:1px solid #EDEDED;
border-radius: 3px 3px 0 0;
-webkit-box-shadow: 0 1px #f5f5f5;
-moz-box-shadow: 0 1px #f5f5f5;
box-shadow: 0 1px #f5f5f5;
}
.register input[type=text], .register input[type=password] ,.register select,.register textarea {
width: 278px;
}
.register p.terms {
float: left;
line-height: 31px;
}
.register p.terms label {
font-size: 12px;
color: #777;
cursor: pointer;
}
.register p.terms input {
position: relative;
bottom: 1px;
margin-right: 4px;
vertical-align: middle;
}
.register-help {
margin: 20px 0;
font-size: 11px;
text-align: center;
color:#FFFFFF;
}
.register-help a {
color:#FF3679;
text-shadow:0 1px #1E0E13;
}
:-moz-placeholder {
color: #404040 !important;
font-size: 13px;
}
::-webkit-input-placeholder {
color: #ccc;
font-size: 13px;
}
input {
font-family:"Trebuchet MS",tahoma;
font-size: 14px;
}
input[type=text], input[type=password] ,.register select,.register textarea {
margin: 5px;
padding: 0 10px;
height: 34px;
color: #404040;
background: #fff;
border-width: 1px;
border-style: solid;
border-color: #c4c4c4 #d1d1d1 #d4d4d4;
border-radius:3px;
--webkit-border-radius: 5px;
outline:3px solid rgba(200, 105, 137, 0.09);
-moz-outline-radius:7px;
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.12);
margin:10px 0;
}
input[type=text]:focus, input[type=password]:focus{
border-color:#FFF7F9;
outline-color:rgba(254, 225, 235, 0.7);
outline-offset: 0;
}
input[type=button] {
padding:0 0px;
height: 29px;
width: 100px;
font-size: 12px;
font-weight: bold;
color:#FFFFFF;
text-shadow:0 1px #4D1124;
border-width: 1px;
border-style: solid;
border-color:#693647;
outline: none;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
background-color: #7D0F33;
}
input[type=button]:active {
background: #7D0F33;
-webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
-moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.2);
}
.lt-ie9 input[type=text], .lt-ie9 input[type=password] {
line-height: 34px;
}
.register select {
padding:6px 10px;
width: 300px;
color: #777777;
}
.register textarea {
height: 50px;
padding: 10px;
color: #404040;
}
/* About */
.about {
margin:10px auto;
width: 300px;
text-align: center;
color:#EEA5BD;
font-size: 12px;
}
.about a {
padding: 1px 3px;
margin: 0 -1px;
color: #fff;
text-decoration: none;
text-shadow: 0 -1px rgba(0, 0, 0, 0.2);
border-radius: 2px;
}
.about a:hover {
color:#2F0916;
text-shadow: none;
background: #E83671;
}
.links {
zoom: 1;
}
.links:before, .links:after {
content: "";
display: table;
}
.links:after {
clear: both;
}
.links a {
padding: 6px 0;
float: left;
width: 50%;
font-size: 14px;
}
.gm-style-iw {
width: 350px !important;
top: 15px !important;
left: 0px !important;
background-color: #fff;
border-radius: 2px 2px 10px 10px;
}
#iw-container {
margin-bottom: 10px;
}
#iw-container .iw-title {
font-family: 'Open Sans Condensed', sans-serif;
font-size: 22px;
font-weight: 400;
padding: 10px;
background-color: #7D0F33;
color: white;
margin: 0;
border-radius: 2px 2px 0 0;
}
#iw-container .iw-content {
font-size: 13px;
line-height: 18px;
font-weight: 400;
margin-right: 1px;
padding: 15px 5px 20px 15px;
max-height: 140px;
overflow-y: auto;
overflow-x: hidden;
}
.iw-subTitle {
font-size: 16px;
font-weight: 700;
padding: 5px 0;
}
.iw-bottom-gradient {
position: absolute;
width: 326px;
height: 25px;
bottom: 10px;
right: 18px;
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
}
I think you should store the marker object inside an array of object. Ex:
var arrayOfMarkers = [];
for (var i = 0; i < data.length; i++) {
// Create a lat/long object readable by Google
var myLatlng = new google.maps.LatLng(parseFloat(data[i][0]), parseFloat(data[i][1]));
// Generate a marker from the lat/long object and add it to the map
var marker = new google.maps.Marker({
position: myLatlng,
map: mapCanvas,
title: data[i][2],
description: data[i][3]
});
arrayOfMarkers.push(marker);
}
Then use the arrayOfMarkers to iterate the event listener for each Info Windows
[Updated - Add Ground Overlay after user clicks the marker]
Please see the demo here : http://codepen.io/dannypranoto/pen/PNdvzb
All you need to do is set up a new function for creating a new Ground Overlay with parameters of imageBound
this.instance = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(40.740, -74.18),
zoom: 13,
});
this.addGroundOverlay = function(data) {
var instance = this.instance;
var groundOverlay = new google.maps.GroundOverlay(
'http://i.stack.imgur.com/0mgx2.jpg',data);
groundOverlay.setMap(instance);
}
Then call the function inside the google.maps.event.addListener(marker, ...)
this.addMarker = function(data) {
var Map = this;
var instance = this.instance;
var content = String.format(this.contentTemplate, data.image_url, data.name, data.summary);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data.latitude, data.longitude),
title: data.name
});
marker.setMap(instance);
google.maps.event.addListener(marker, 'click', function() {
var imageBound = {
north: 40.773941,
south: 40.712216,
east: -74.12544,
west: -74.22655
}
Map.addGroundOverlay(imageBound);
});
}
So on my site I'm using Google Maps + Streetview:
https://developers.google.com/maps/documentation/javascript/examples/streetview-simple
Also I'm using standard searchbox with autocomplete, the problem is when I enter some locations, there is no streetview, just Photo Sphere image without any controls for moving around like in standard streetview...
I really don't want Photo Sphere, because I want my users to freely move around with street view, and now they sometimes get "trapped" in one Photo Sphere image... Is there a way I can force streetview without Photo Sphere?
I'm not sure how to turn off PhotoSpheres, but I did find a workaround that may be useful to you. I noticed at https://developers.google.com/maps/documentation/javascript/reference#StreetViewSource that when searching for a location, if you set the source to OUTDOOR, then PhotoSpheres are not returned.
Therefore, if you add listeners for location changes, and then search for the location without PhotoSpheres, I think you should be able to prevent them from showing up.
Here is a modified google maps example to illustrate:
<!DOCTYPE html>
<html>
<head>
<title>Place Autocomplete without PhotoSpheres</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map, #pano {
height: 100%;
width: 50%;
float:left;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
</head>
<body>
<input id="pac-input" class="controls" type="text"
placeholder="Enter a location">
<div id="map"></div>
<div id="pano"></div>
<script>
var map;
var panorama;
var streetViewService;
var DEFAULT_PROXIMITY = 50;
var MAX_PROXIMITY = 10000;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.8688, lng: 151.2195},
zoom: 13
});
var input = /** #type {!HTMLInputElement} */(
document.getElementById('pac-input'));
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var autocomplete = new google.maps.places.Autocomplete(input);
//autocomplete.bindTo('bounds', map);
streetViewService = new google.maps.StreetViewService();
panorama = new google.maps.StreetViewPanorama(
document.getElementById('pano'), {
position: {lat: -33.8688, lng: 151.2195},
pov: {
heading: 34,
pitch: 10
}
});
map.setStreetView(panorama);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
window.alert("Autocomplete's returned place contains no geometry");
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.location) {
findClosestStreetView(place.geometry.location, DEFAULT_PROXIMITY);
}
});
function findClosestStreetView(point, proximity) {
streetViewService.getPanorama({location: point, radius: proximity, source: google.maps.StreetViewSource.OUTDOOR}, function processSVData(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
map.panTo(data.location.latLng);
panorama.setPano(data.location.pano);
} else {
if (proximity < MAX_PROXIMITY) {
findClosestStreetView(point, proximity + 50);
} else {
// NO PANARAMA FOUND - do something else here...
panorama.setVisible(false);
}
}
});
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?&libraries=places&callback=initMap" async defer></script>
</body>
</html>
I'm appending a Search Results to the google places javascript api autocomplete.
So far I'm doing this:
var autocomplete;
function initialize() {
var myLatlng = new google.maps.LatLng(40.738793, -73.991402);
autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'));
}
later on I have this:
$('.pac-container').append( '<div class="j-search pac-item-refresh">Search Results</div>' );
$(document.body).on('click', '.pac-container .j-search', function(e) {
console.log('click fired');
});
The problem? The click event never fires...
Any idea why? Anything wrong with my code?
It seems that the click-event for .pac-container is cancelled by the Autocomplete-instance. Use mousedown instead.
You can follow the this article.
Implement and Optimize Autocomplete with Google Places API
Specifically Autocompletion using the AutocompleteService:
link: JS Filddle Of AutocompletionService
function debounce(func, wait, immediate) {
let timeout;
return function() {
let context = this,
args = arguments;
let later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
function initAutocomplete() {
let map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 48,
lng: 4
},
zoom: 4,
disableDefaultUI: true
});
// Create the search box and link it to the UI element.
let inputContainer = document.querySelector('autocomplete-input-container');
let autocomplete_results = document.querySelector('.autocomplete-results');
let service = new google.maps.places.AutocompleteService();
let serviceDetails = new google.maps.places.PlacesService(map);
let marker = new google.maps.Marker({
map: map
});
let displaySuggestions = function(predictions, status) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
alert(status);
return;
}
let results_html = [];
predictions.forEach(function(prediction) {
results_html.push(`<li class="autocomplete-item" data-type="place" data-place-id=${prediction.place_id}><span class="autocomplete-icon icon-localities"></span> <span class="autocomplete-text">${prediction.description}</span></li>`);
});
autocomplete_results.innerHTML = results_html.join("");
autocomplete_results.style.display = 'block';
let autocomplete_items = autocomplete_results.querySelectorAll('.autocomplete-item');
for (let autocomplete_item of autocomplete_items) {
autocomplete_item.addEventListener('click', function() {
let prediction = {};
const selected_text = this.querySelector('.autocomplete-text').textContent;
const place_id = this.getAttribute('data-place-id');
let request = {
placeId: place_id,
fields: ['name', 'geometry']
};
serviceDetails.getDetails(request, function(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var bounds = new google.maps.LatLngBounds();
marker.setPosition(place.geometry.location);
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
}
autocomplete_input.value = selected_text;
autocomplete_results.style.display = 'none';
});
})
}
};
let autocomplete_input = document.getElementById('my-input-autocomplete');
autocomplete_input.addEventListener('input', debounce(function() {
let value = this.value;
value.replace('"', '\\"').replace(/^\s+|\s+$/g, '');
if (value !== "") {
service.getPlacePredictions({
input: value
}, displaySuggestions);
} else {
autocomplete_results.innerHTML = '';
autocomplete_results.style.display = 'none';
}
}, 150));
}
document.addEventListener("DOMContentLoaded", function(event) {
initAutocomplete();
});
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.autocomplete-input-container {
position: absolute;
z-index: 1;
width: 100%;
}
.autocomplete-input {
text-align: center;
}
#my-input-autocomplete {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.16), 0 0 0 1px rgba(0, 0, 0, 0.08);
font-size: 15px;
border-radius: 3px;
border: 0;
margin-top: 10px;
width: 290px;
height: 40px;
text-overflow: ellipsis;
padding: 0 1em;
}
#my-input-autocomplete:focus {
outline: none;
}
.autocomplete-results {
margin: 0 auto;
right: 0;
left: 0;
position: absolute;
display: none;
background-color: white;
width: 320px;
padding: 0;
list-style-type: none;
margin: 0 auto;
border: 1px solid #d2d2d2;
border-top: 0;
box-sizing: border-box;
}
.autocomplete-item {
padding: 5px 5px 5px 35px;
height: 26px;
line-height: 26px;
border-top: 1px solid #d9d9d9;
position: relative;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.autocomplete-icon {
display: block;
position: absolute;
top: 7px;
bottom: 0;
left: 8px;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center center;
}
.autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality.svg);
}
.autocomplete-item:hover .autocomplete-icon.icon-localities {
background-image: url(https://images.woosmap.com/icons/locality-selected.svg);
}
.autocomplete-item:hover {
background-color: #f2f2f2;
cursor: pointer;
}
.autocomplete-results::after {
content: "";
padding: 1px 1px 1px 0;
height: 18px;
box-sizing: border-box;
text-align: right;
display: block;
background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white3_hdpi.png);
background-position: right;
background-repeat: no-repeat;
background-size: 120px 14px
}
<div class="autocomplete-input-container">
<div class="autocomplete-input">
<input id="my-input-autocomplete" placeholder="AutocompleteService" autocomplete="off" role="combobox">
</div>
<ul class="autocomplete-results">
</ul>
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback"></script>
I am writing because I have made a script that takes the json data to create multiple dynamic marker, and it works!
Now I'm trying to add the InfoWindow to each marker, but does not work.
My code is:
$.ajax({
type:'GET',
url:"locali_json.php"+urlz,
success:function(data){
var json = JSON.parse(data);
for (var i=0; i<json.length; i++) {
point = new google.maps.LatLng(json[i].latitudine,json[i].longitudine);
contentString = json[i].id_locale;
addMarkers(point,contentString);
}
}
})}
function addMarkers(point,contentString) {
marker = new google.maps.Marker({
position: point,
map: map
});
infowindow = new google.maps.InfoWindow({
content: contentString
});
markers.push(marker); // markers is an array
infos.push(infowindow); //info is an array
for(var j=0; j<markers.lenght; j++){
google.maps.event.addListener(marker, 'click', function() {
infos[j].open(map,markers[j]);})
}}
anyone have any suggestions? or see where error?
Don't you get javascript errors in the javascript console?
for(var j=0; j<markers.lenght; j++){
google.maps.event.addListener(marker, 'click', function() {
infos[j].open(map,markers[j]);})
}
}
Should probably be:
for(var j=0; j<markers.length; j++){
google.maps.event.addListener(markers[j], 'click', function() {
infos[j].open(map,markers[j]);})
}
}
I did it this way, you can try it. Includes a customized info window.
Index.cshtml
#{
Layout = null;
}
<html>
<head>
<style>
#map-canvas {
margin: 0;
padding: 0;
height: 400px;
max-width: none;
}
.gm-style-iw {
width: 350px !important;
/*top: 0px !important;
left: 0px !important;
background-color: #fff;
box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
border: 1px solid rgba(72, 181, 233, 0.6);
border-radius: 10px 10px 10px 10px;*/
}
#iw-container {
margin-bottom: 10px;
}
#iw-container .iw-title {
font-family: 'Open Sans Condensed', sans-serif;
font-size: 22px;
font-weight: 400;
padding: 20px;
background-color: #39ac73;
color: white;
margin: 2px;
border-radius: 2px 2px 0 0;
}
#iw-container .iw-content {
font-size: 13px;
line-height: 18px;
font-weight: 400;
margin-right: 1px;
padding: 15px 5px 20px 15px;
max-height: 200px;
overflow-y: auto;
overflow-x: hidden;
}
#map-canvas img {
max-width: none !important;
}
.iw-subTitle {
font-size: 16px;
font-weight: 700;
padding: 5px 0;
}
.infoDiv {
height: 200px;
width: 300px;
-webkit-user-select: none;
background-color: white;
}
.iw-bottom-gradient {
position: absolute;
width: 326px;
height: 25px;
bottom: 10px;
right: 18px;
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
}
</style>
</head>
<body>
<div id="map-canvas" style="width: 1800px; height: 1500px">
</div>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=APIKEY"></script>
<script type="text/javascript">
var markers = #Html.Raw(ViewBag.Markers);
window.onload = function () {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
description: data.description,
icon: "http://maps.google.com/mapfiles/ms/icons/green-dot.png",
animation: google.maps.Animation.DROP,
});
// Add the circle for this city to the map.
var cityCircle = new google.maps.Circle({
strokeColor: '#FFFFFF',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FFFFFF',
fillOpacity: 0.35,
map: map,
center: myLatlng,
radius: 19999.45454,
position: myLatlng,
draggable: false
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent('<div id="iw-container">' +
'<div class="iw-title">' + data.title + "</div>" + '<div class="iw-content">'
+ "<p>" + data.description + "</p>"+'<img src="http://maps.marnoto.com/en/5wayscustomizeinfowindow/images/vistalegre.jpg" alt="Porcelain Factory of Vista Alegre" height="115" width="83">'
+'<div class="iw-bottom-gradient"></div>');
//infoWindow.setContent(data.title);
//infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
}
</script>
</body>
</html>
Controller:
namespace Map.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
{
string markers = "[";
string conString = ConfigurationManager.ConnectionStrings["PTS"].ConnectionString;
SqlCommand cmd = new SqlCommand("SELECT * FROM ProjeIlani");
using (SqlConnection con = new SqlConnection(conString))
{
cmd.Connection = con;
con.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
markers += "{";
markers += string.Format("'title': '{0}',", sdr["Adres"]);
markers += string.Format("'lat': '{0}',", sdr["Enlem"]);
markers += string.Format("'lng': '{0}',", sdr["Boylam"]);
markers += string.Format("'description': '{0}'", sdr["Aciklama"]);
markers += "},";
}
}
con.Close();
}
markers += "];";
ViewBag.Markers = markers;
return View();
}
}
}
}